I would like a test runner that detects when I have changed tests/code, and runs the relevant tests.

— Daniel Watkins (@Odd_Bloke) January 31, 2013



This "test harness" is actually a bash snippet which relies on inotifywait This "test harness" is actually a bash snippet which relies on, a command-line program which blocks until it detects an inotify event on the files it is watching, and is incredibly simple:

while inotifywait -e close_write -r $CODE_DIRS --exclude=".*sw[px]"; do $TEST_COMMAND done

while

inotifywait

$TEST_COMMAND

inotifywait

$CODE_DIRS

inotifywait

-e

close_write

file or directory closed, after being opened in writable mode

modify

move

create

-e

-r

inotifywait

-r

--exclude

Recently, I tweeted about my desire for a change-aware test runner:I haven't quite come up with that (though I do now have a half-finished blog post prognosticating on it), but I do have a solution which covers some of the bases: I determine what tests I want to run, and the test harness runs them whenever my code changes.Thisloop is simple. When thecommand stops blocking (and with exit code 0, which it will unless something unusual has happened to the files you're watching), we run. You can put whatever you want there, so you could limit the number of tests you run that way.Now let's break thatcall down.can be any number of directories or files that you would liketo watch.narrows down the events that we should unblock on; we don't want to run the tests every time we open a new file.triggers on (to quote the man page):vim triggers this when I save, so it works for me. You might also want to listen for(file or directory contents were written),(file or directory moved to or from watched directory) and(file or directory created within watched directory). Multipleoptions are comma-separated., as with many commands, tellsto watch directories recursively. This will mean that all directories under those that you specify will trigger your tests. I normally just run this command pointing at the top-level directory of my project. It's worth noting thatapplies to all directories that you pass.Finally,takes a regular expression of files to exclude from your watch. As a vim user who hasn't configured swap files to be stored out of my tree, I want to ignore them (otherwise my tests run every time I open a file because vim writes out a swap file).A quick disclaimer: as this uses inotify, this will only work on platforms that support it (which, I think, is only Linux). Mac users might want to examine this StackOverflow question . Windows users might find this answer useful. +Murali Suriar has helpfully pointed me to kqwait on IRC, which will help out any Mac/BSD users.