Testing Shell Scripts
Getting Started
The best way I have found to unit test shell scripts is rather simple and comes from JSON.sh[1] (I've changed this a little bit for my own use):
#!/bin/sh
# Set current directory to the current file
cd "${0%/*}" || exit 1
fail=0
tests=0
passed=0
for test in tests/*.sh ; do
tests=$((tests+1))
echo "TEST: $test"
if "./$test"; then
echo "OK: ---- $test"
passed=$((passed+1))
else
echo "FAIL: $test"
fail=$((fail+ret))
fi
done
if [ "$fail" -eq 0 ]; then
echo 'SUCCESS'
exitcode=0
else
echo 'FAILURE'
exitcode=1
fi
echo "$passed / $tests"
exit $exitcode
Essentially what this does is it:
- runs each test within the
tests
folder; - records each test's exit code, determining if the test succeeded (
0
) or failed (anything else); - shows the result of each test and the suite as a whole when complete.
I haven't written super complex shell scripts yet, but I feel like this gives enough flexibility to work with simple unit testing in basic applications.
Another advantage is that meta files, like set up and tear down, can be kept in a file preceded by .
, as they will be skipped by the above glob.
Examples
An example of this could be testing a function called capitalize
. First, we write the above test runner to the root folder and then make the test file in our tests
folder:
tests/capitalize.sh
cd ${0%/*}
source "../capitalize.sh"
fails=0
words=(bob john Jane ron-jon)
expected_words=(Bob John Jane Ron-jon)
for word in "${words[@]}"; do
i=$((i + 1))
result="$(capitalize "$word")"
if [ "$result" != "${expected_words[i]}" ]; then
fails=$((fails + 1))
fi
done
exit $fails
And then we run the test runner and see that it failed before writing the actual function.
capitalize.sh
capitalize() {
# imagine this capitalizes things and returns the capitalized word
}
If you want to test using external files, you can change the for
loop above to a glob, like
for file in ./mock_data/*; do
References
- https://github.com/dominictarr/JSON.sh
- https://thomaslevine.com/computing/shell-testing/
- https://poisel.info/posts/2022-05-10-shell-unit-tests/
Last modified: 202401040446