tests-shelllisted
Install: claude install-skill johantor/zion
# Backend tests: shell (bats / plain-bash harness)
Detect the shape — shell projects use one of two, and they are not interchangeable:
- **`*.bats` files, or `bats` in CI** → [bats-core]. `@test "name" { … }`, `run <cmd>` then assert
on `$status` and `$output`, `setup`/`teardown` per test, `setup_file`/`teardown_file` per file.
- **A plain-bash harness** (a `tests/` directory of `*.test.sh` plus a `lib.sh` of assertions, run
by a `run.sh`) → follow the harness that is there. Read its assertion helpers first and use
them; do not introduce bats beside it.
## What a shell test asserts
A script's observable behavior is its **exit code**, its **stdout/stderr**, and the **files it
touched**. Assert on the ones that matter and say which:
- Exit code for a script whose job is to pass or fail (a guard, a check, a validator).
- Output for a script whose job is to produce something — match a substring, not the whole stream,
so unrelated wording changes don't fail the test.
- Filesystem state for a script that writes: build the fixture, run, then assert on what is there.
**Test both directions.** A guard tested only on what it blocks will pass while blocking
everything; one tested only on what it allows will pass while blocking nothing. Every rule needs
an allow case and a block case, and a new rule lands with both.
## Fixtures
Build a throwaway tree per case rather than sharing mutable state between tests. Use the harness's
own helper if it has one; otherwise `mktemp -d