← ClaudeAtlas

bats-testing-patternslisted

Bats test patterns for shell scripts and CLI tools (`.bats` files, `run`, `setup`/`teardown`, PATH-stub mocking, CI wiring). Use when adding tests to a bash/shell script, hardening its error paths, or wiring `bats-core` into CI.
uwuclxdy/agenticat · ★ 5 · Testing & QA · score 80
Install: claude install-skill uwuclxdy/agenticat
# Bats Testing Patterns Bats (`bats-core`) runs `.bats` files as TAP-compliant Bash tests. Each `@test` block runs in its own subshell/process; state never leaks between tests. `export` a variable when a command run via `run` within the same test needs to see it. ## Test File Anatomy ```bash #!/usr/bin/env bats setup() { # before EACH test export SCRIPT="${BATS_TEST_DIRNAME}/../bin/script.sh" } setup_file() { # once, before the file's first test export FIXTURE_DB="$BATS_FILE_TMPDIR/seed.db" } @test "script exits 0 with a valid config" { run "$SCRIPT" --config "$BATS_TEST_TMPDIR/valid.conf" [ "$status" -eq 0 ] } ``` `teardown` mirrors `setup` and runs after every test; skip it when `$BATS_TEST_TMPDIR` already covers cleanup. Use `$BATS_TEST_TMPDIR` (unique per test) instead of hand-rolled `mktemp -d`/`rm -rf`: bats creates and clears it automatically, so a test can't leak state into the next one even if `teardown` never runs. `$BATS_FILE_TMPDIR` is the per-file equivalent for `setup_file`/`teardown_file`; `$BATS_SUITE_TMPDIR` spans the whole suite. ## The `run` Helper `run` captures a command's exit status into `$status` and its combined stdout+stderr into `$output` (also split into the `$lines` array). It always returns 0, so the test keeps going after a failing command. ```bash @test "rejects an unknown flag" { run -1 my_script --bogus # -N: assert exit status N; bare `!` asserts any nonzero [[ "$o