So I'm quite fond of using a simple script to execute my script's unit tests whenever I save it. This concept is not new, and certainly not an original idea in itself, but the simplicity of an editor independent unit test executor in 10 lines of code has a certain appeal for me:
#!/bin/bash
stat_command="stat -c '%Y'"
file_name=$1
last_modification=""
while true; do
current_modification=$( $stat_command $file_name )
if [ "$current_modification" != "$last_modification" ]; then
clear
$file_name --test
last_modification=$current_modification
fi
sleep 1
done
This script stats the script file until it detects a change. Whenever a change is detected, the script is called with --test, which is my personal way to tell a script that it should just execute it's unit tests and exit. See my blog post about integrating unit tests in Ruby scripts to learn how this can be done in Ruby. A very similar approach is possible for Python:
#!/usr/bin/python
import unittest
import sys
if sys.argv.count("--test") > 0:
sys.argv.remove("--test")
unittest.main()
Now I can simply call the test bash script, giving it the script under test as parameter:
./run_tests.sh ./script_under_test.py
The beauty lies in the simplicity of the solution: Even when I remote edit a script on some server with vi, I can simply launch a new console and execute run_tests.sh, watching the test results whenever I type ":w".
Update: The "sleep 1" really helps to keep I/O load down. Thanks to Philip for pointing this out. And yet another nice example of how hard it is to write 10 lines of bugfree code without a test.