Skip to main content

Test Writer (BATS)

The Test Writer skill provides context injection for creating comprehensive tests using the BATS (Bash Automated Testing System) framework.

Overview

PropertyValue
Skill IDct-test-writer-bats
Tier2 (Execution)
Protocolimplementation
Tagstesting, bats, integration

Capabilities

  1. Integration Tests - Test command workflows end-to-end
  2. Unit Tests - Test individual functions
  3. Fixture Creation - Create test data and mocks
  4. Error Case Testing - Verify error handling

When to Use

The dispatch algorithm selects ct-test-writer-bats for:
  • Tasks with keywords: test, bats, coverage
  • Tasks labeled: testing
  • Task type: testing

Test Structure

Directory Layout

tests/
├── integration/          # End-to-end workflow tests
│   └── {feature}.bats
├── unit/                 # Individual function tests
│   └── {module}.bats
├── fixtures/             # Test data
│   └── {feature}/
├── test_helper/          # BATS support libraries
│   ├── bats-support/
│   └── bats-assert/
└── run-all-tests.sh      # Test runner

Basic Test File

#!/usr/bin/env bats

# Load test helpers
load '../test_helper/bats-support/load'
load '../test_helper/bats-assert/load'

# Setup runs before each test
setup() {
  export TEST_DIR=$(mktemp -d)
  cd "$TEST_DIR"
}

# Teardown runs after each test
teardown() {
  cd /
  rm -rf "$TEST_DIR"
}

@test "descriptive name explaining what is tested" {
  # Arrange
  # ... setup test conditions

  # Act
  run command_under_test

  # Assert
  assert_success
  assert_output --partial "expected"
}

@test "error case: handles missing input" {
  run command_under_test --missing-arg
  assert_failure
  assert_output --partial "error"
}

BATS Assertions

Status Assertions

assert_success              # Exit code 0
assert_failure              # Exit code non-zero
assert_equal "$actual" "$expected"

Output Assertions

assert_output "exact match"
assert_output --partial "substring"
assert_output --regexp "pattern.*match"
refute_output --partial "should not contain"

File Assertions

assert [ -f "$file" ]       # File exists
assert [ -d "$dir" ]        # Directory exists
assert [ -s "$file" ]       # File is not empty

Test Categories

Happy Path Tests

@test "command succeeds with valid input" {
  run cleo add "Test task"
  assert_success
  assert_output --partial "T"
}

Error Handling Tests

@test "command fails with invalid task ID" {
  run cleo show INVALID
  assert_failure
  assert_output --partial "not found"
}

Integration Tests

@test "full workflow: create, update, complete" {
  # Create
  run cleo add "Test task"
  assert_success
  local task_id=$(echo "$output" | jq -r '.task.id')

  # Update
  run cleo update "$task_id" --priority high
  assert_success

  # Complete
  run cleo complete "$task_id"
  assert_success
}

Test Isolation

Tests MUST be idempotent:
setup() {
  # Always use temp directory
  export TEST_DIR=$(mktemp -d)
  cd "$TEST_DIR"
  cleo init test-project --yes 2>/dev/null || true
}

teardown() {
  # Always clean up
  cd /
  rm -rf "$TEST_DIR"
}

Never

  • Modify files outside TEST_DIR
  • Depend on global state
  • Assume test execution order
  • Leave artifacts after test

Running Tests

# Run single test file
bats tests/integration/{feature}.bats

# Run all tests
./tests/run-all-tests.sh

# Run with verbose output
bats --verbose-run tests/integration/{feature}.bats

# Run specific test
bats tests/integration/{feature}.bats --filter "test name"

Execution Flow

1. Read task details
2. Set focus
3. Create test file(s)
4. Run tests and verify pass
5. Write output and manifest
6. Complete task
7. Return summary