- Install bats-core with its helper libraries (`bats-support`, `bats-assert`, `bats-file`) as git submodules under `test/helpers/`.
- Use `run` before every command under test so Bats captures `$status` and `$output` without short-circuiting on non-zero exits.
- Load helpers at the top of each `.bats` file: `load 'helpers/bats-support/load'` then `load 'helpers/bats-assert/load'`.
- Use `assert_success` and `assert_failure` instead of `[ "$status" -eq 0 ]` — they provide descriptive output including the captured command output on failure.
- Use `assert_output --partial 'expected text'` for partial output matching instead of `grep`-ing `$output` manually.
- Use `setup_file()` for one-time expensive setup (e.g., building a Docker image) and `setup()` for per-test setup to minimize redundant work.
- Tag tests with `# bats test_tags=slow` and skip them in fast CI runs with `bats --filter-tags '!slow'`.