« Copyright Alliance desires Death of Public Domain | Main | Random Tea Research »

ShUnit - shell code unit testing

2008-05-11 update: shUnit2 is a unit testing framework for shell scripts modeled after the JUnit framework. It is designed to make unit testing in shell as simple as possible. I have not had a chance to review it yet, though may serve shell unit testing needs better than ShUnit (detailed below) does.

ShUnit is a unit testing framework for Bourne shell code. It does not ameliorate problems with syntax errors, but will confirm that the code behaves as expected, to the depth that unit tests can be written. Scripts bereft of modular design will benefit the least, as discrete functions offer more testing opportunities. The say_something script, shown below, employs a say_something function. This function is called directly from the unit test script. Additional unit tests could also run the say_something script and parse the output. Without this modular design, the unit test would be restricted to running the script and inspecting the output.

#!/bin/sh # say_something - a testable script say_something() { echo "$1" } broken_say_something() { echo $$ } say_something "uh oh I ran"

#!/bin/sh # say_something.test - unit tests for say_something . ShUnit-1.3/shUnit # source here requires no modification of the script being tested . say_something TestSaySomething() { EXPECTED="this is a test" RESULT=`say_something "$EXPECTED"` test "${EXPECTED}" = "${RESULT}" shuAssert "Test say_something" $? } TestBrokenSaySomething() { EXPECTED="this is a test" RESULT=`broken_say_something "$EXPECTED"` test "${EXPECTED}" = "${RESULT}" shuAssert "Test broken say_something" $? } InitFunction() { shuRegTest TestSaySomething shuRegTest TestBrokenSaySomething } shuStart InitFunction

$ sh say_something.test uh oh I ran ****** say_something.test ****** 2 tests to run: Test 1: TestSaySomething . Test 2: TestBrokenSaySomething E "Test broken say_something" failed. 2 tests run. 1 test succeeded.

However, whether sourced or executed, the code tested will run, evidenced by the uh oh I ran output, above. This may require an “is this the test mode?” workaround in the script, or that all the functions be moved to a library file that both the actual and any unit test scripts read from (an excellent design idea).

After my admittedly brief investigation, shUnit requires more code per test than Test::More for Perl. However, the included shUnitPlus library contains additional convenience functions that could further simplify the shell code. As a final plus, ShUnit employs clean design and clever code, and therefore makes for an edifying study.

Technorati Tags: