bash: Unit testing using `shunit2`
A bash script can declare functions with the name test...
in order for the shunit2
unit testing tool to automatically discover and run them as tests.
Co-locating tests
To colocate tests with the code they test, define the test...
functions inside another function, RunTests
, that is conditionally run via a command line flag.
For example, given the following executable script, foo.sh
, you could run the script with ./foo.sh
and run the tests with ./foo.sh --test
:
# Library functions
function lib() { echo "result" ; }
# etc.
# Main script entrypoint
function RunMain() { echo "TODO" ; }
# Test script entrypoint
function RunTests() {
# Tests
function testFoo() { assertEquals "1" "1"; }
function testBar() { assertEquals "result" "$(lib)"; }
function testBaz() { assertEquals "1 2 result" "$("$0" 1 2)"; }
# etc.
# Run tests
source shunit2
}
# Choose an entry point
expr "$*" : ".*--test" > /dev/null && RunTests || RunMain
Separating tests
Alternatively, define tests in a separate file that sources the original. Be careful that the main script does not execute when sourced.
Main script, foo.sh
:
# Library functions
function lib() { echo "result" ; }
# etc.
# Main script entrypoint
function RunMain() { echo "TODO" ; }
# Do not execute when sourced
[[ "${BASH_SOURCE[0]}" == "${0}" ]] && RunMain
Test script, foo_test.sh
:
# Source main script to make functions available
source foo.sh
# Tests
function testFoo() { assertEquals "1" "1"; }
function testBar() { assertEquals "result" "$(lib)"; }
# etc.
# Run tests
source shunit2
Published on: 27 Sep 2022