Writing quick tests in Bash

Leveraging existing knowledge can make testing with Bash quick and extensible. Setup requires an assertion function and some imagination to repurpose commands you may already use.

Assertions in Bash

To test, you must assert. One starting place is to adapt code from the Advanced Bash Scripting Guide.

After modification, my own assert function looks like this:

# params: Message, Assertion
assert() {
E_PARAM_ERR=98
E_ASSERT_FAILED=99

if [ -z "$2" ]
then
return $E_PARAM_ERR
fi

message=$1
assertion=$2

if [ ! $assertion ]
then
echo "❌ $message"
exit $E_ASSERT_FAILED
else
echo "✅ $message"
return
fi
}

# Examples:
assert "Passes when true" "1 == 1"
assert "Fails when false" "1 == 2"

My main modification was to show test results with a message and emoji.

Terminal output showing results of tests

With an assert function, you can test results of functions and expressions.

Curl for API tests

To test API endpoints, use curl.

Imagine wanting to assert that a response contains specific text -- curl and grep can handle that case.

assert "Web developer shows on homepage" "1 == $(curl -S -L 2>/dev/null christianwood.net | grep -c 'web developer')"

Maybe you only care about the status code returned by an endpoint. Try this:

assert "Returns 200 response" "200 == $(curl -sLo /dev/null -I -w '%{http_code}' christianwood.net)"

Writing tests like these reminds me that curl holds a lot of power. You can POST, follow redirects, add headers -- basically anything you might want to test an API.

Conclusion

Testing with Bash offers a quick, simple testing option. Moreover, if desired, you can add the scripts to Continous Integration.

The cons, of course, include all the cons of Bash scripting in general -- occassional arcane syntax, minor differences between systems, etc.

More fully-featured libraries exist for testing in Bash, like bash_unit. I have not used these libraries, but suspect they would be a superior choice for projects with more refined requirements. See this Stack Overflow post for further conversation.