Skip to content
shellhacks.dev
Testing

Write a Bats test

Write a Bats test file with @test blocks, run it with the bats command, and read the TAP output. A test passes when every command in it exits 0.

1 min read
Summarize in AI

You want to test a shell function the way you test code in any other language, with named cases and a pass or fail result.

Shell
cat > test.bats <<'EOF'
@test "addition works" {
  result=$((2 + 3))
  [ "$result" -eq 5 ]
}

@test "grep finds a word" {
  echo "hello world" | grep -q world
}

@test "this one fails" {
  [ "$((2 + 2))" -eq 5 ]
}
EOF
bats test.bats
echo "exit: $?"
Text
1..3
ok 1 addition works
ok 2 grep finds a word
not ok 3 this one fails
# (in test file test.bats, line 11)
#   `[ "$((2 + 2))" -eq 5 ]' failed
exit: 1

Each @test block becomes a shell function that runs with set -e in effect, so the first command that returns non-zero fails the test, which is why a bare [ ... ] is an assertion. Bats prints the TAP format, a plan line followed by an ok or not ok for each case, and for a failure it names the file, the line and the command that failed.

The exit status of bats is 1 when any test fails, so it works as a CI step. A command that fails inside an if or after || does not trip set -e, so write assertions as plain commands. The output here is from Bats 1.8.2, and the @test syntax needs the bats runner and is not valid Bash on its own.

Share

More snippets

Testing

Choose the shell for ShellCheck

Tell ShellCheck which shell a script targets with -s bash or -s sh. Without a shebang it cannot tell, and as sh it flags every Bash-only feature as SC3xxx.

2 min read
Testing

Skip a Bats test

Skip a Bats test with skip or skip "reason", which can be called in the middle of a test. A skipped test counts as passed, and the reason shows in the output.

2 min read
Testing

Load helpers in Bats

Share code between Bats tests with load helpers, which reads helpers.bash from the test file's directory. A plain source breaks when bats runs from elsewhere.

2 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.