Continuous Testing, Productivity++
Wednesday, January 20th, 2010While preparing to present Watchr at CUSEC’s DemoCamp, I’ve come accross this research paper about continuous testing. From the research:
While preparing to present Watchr at CUSEC’s DemoCamp, I’ve come accross this research paper about continuous testing. From the research:
Like lots of rubyists, I love agile development, BDD/TDD and continuous
testing. And one of my favourite pieces of software for that task is Autotest. Whenever I start a new project, the first thing I do is open up a test file, write a placeholder test case, and fire up autotest. It’s the one gem I use on every single application I write; from gems to rails apps to bare bones rack apps, it’s always there to make my development much more enjoyable.
Well, almost always.
Some time ago I was working on a gem where I wanted to use the Expectations test framework. Expectations is not based on test/unit (as opposed to context or contest, for instance). But Autotest, by default, requires test/unit. The result wasn’t great.
Not too long ago, I was getting excited about rip, an alternative ruby package manager. So I tried using it. But autotest automatically requires rubygems. Not so compatible.
Not too long ago I started working on a webapp that has regular MRI based tests alongside JRuby based tests. But Autotest automatically ran the test suite with /usr/bin/ruby1.8. That just plain won’t work.
“Hi. I’m Martin …. and I’m a continuous testing addict”
I was beginning to feel the withdrawal symptoms. So I started working on a solution that would satisfy my cravings in any dev environment. The result is Watchr, a continuous testing tool similar to autotest, but with a different philosophy.
Watchr aims to be much more flexible, at the cost of a few lines of setup. That is, it will read a small script file and run tests accordingly. The script file uses a very simple ruby DSL. Very simple as in a single method, that’s all it needs.
# pattern action
watch('test/test_.*\.rb') {|md| system "ruby #{md[0]}"}
This tells watchr to monitor all test files (in this case all ruby files in the test/ directory that start with “test_”), and when one of those is saved, runs it with ruby. A continuous testing script for a basic project could be
watch('test/test_.*\.rb') {|md| system "ruby #{md[0]}"}
watch('lib/(.*)\.rb') {|md| system "ruby test/test_#{md[1]}.rb"}
which, in addition to running any saved test file as above, will also run a lib file’s associated test. This mimics the equivalent autotest behaviour.
The command follows the structure:
watch('pattern') {|match_data_object| command_to_run }
Leaving the action user defined is the key. You can run JRuby-based tests, use rip, write your test suite with alternative testing frameworks, … or any combination of these.
For a good example of actual scripts, be sure to check out watchr’s own specs.watchr and docs.watchr scripts.
Install:
gem install watchr --source=http://gemcutter.org
Run:
$ cd to/your/project/root $ watchr path/to/script
source: http://github.com/mynyml/watchr
wiki: http://wiki.github.com/mynyml/watchr
bug tracker: http://github.com/mynyml/watchr/issues