Skip to content
shellhacks.dev
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
Summarize in AI

A helper file sourced from a test works on your machine and fails in CI, which starts Bats from a different directory.

Shell
mkdir -p tests
cat > tests/helpers.bash <<'EOT'
greet() { echo "hello $1"; }
EOT
cat > tests/with_load.bats <<'EOT'
load helpers

@test "load finds the helper next to the test" {
  run greet ada
  [ "$output" = "hello ada" ]
}
EOT
cat > tests/with_source.bats <<'EOT'
source tests/helpers.bash

@test "source depends on the current directory" {
  run greet ada
  [ "$output" = "hello ada" ]
}
EOT
dir=$PWD
bats tests/with_load.bats tests/with_source.bats | head -n 3
echo ---
cd / && bats "$dir/tests/with_load.bats" "$dir/tests/with_source.bats" 2>&1 | head -n 6
Text
1..2
ok 1 load finds the helper next to the test
ok 2 source depends on the current directory
---
1..2
ok 1 load finds the helper next to the test
not ok 2 setup_file failed
# (in test file /tmp/run/S1905-1/w/tests/with_source.bats, line 1)
#   `source tests/helpers.bash' failed with status 0
# /tmp/run/S1905-1/w/tests/with_source.bats: line 1: tests/helpers.bash: No such file or directory

load name looks for name.bash in the directory of the test file, so it works wherever Bats is started from. The other file uses source with a path relative to the project root, which works only while that root is the current directory, and the second run from / shows it failing before any test runs. The command is documented in the Bats manual.

load adds .bash to the name unless the name already ends in it, and an absolute path is used as it is. For helper libraries installed elsewhere, such as bats-assert, load them by an absolute path or one built from BATS_TEST_DIRNAME. Code in a loaded file runs once per test, since every test is its own process, so keep it quick.

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

Check status in Bats

Check a command's exit code in Bats with run and $status. run never fails the test by itself, and Bats 1.5 added run -N to assert the status in one line.

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

Get new posts by email

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

Unsubscribe in one click. No spam, ever.