When writing more then a trivial script in bash, I often wonder how to make the code testable.
It is typically hard to write test for bash code, due to the fact that it is low on functions that take value and return a value, and high on functions that check and set some aspect in the environment, modify the file-system, invoke a program, etc. Thus the setup and test code become much more complicated from the code it tests.
For example, consider a simple function to test:
function add_to_file() {
local f=$1
cat >> $f
sort -u $f -o $f
}
Test code for this function might consist of:
add_to_file.before:
foo
bar
baz
add_to_file.after:
bar
baz
foo
qux
And test code:
function test_add_to_file() {
cp add_to_file.{before,tmp}
add_to_file add_to_file.tmp
cmp add_to_file.{tmp,after} && echo pass || echo fail
rm add_to_file.tmp
}
Here 5 lines of code, are tested by 6 lines of code and 7 lines of data.
Now consider a slightly more complicated case:
function distribute() {
local file=$1 ; shift
local hosts=( "$@" )
for host in "${hosts[@]}" ; do
rsync -ae ssh $file $host:$file
done
}
I can't even say how to start write a test for that...
So, is there a good way to do TDD in bash scripts, or should I give up and put my efforts elsewhere?