Note that the name and locations of this project have changed. The new name and locations in this article have been updated to reflect this. See the Headless Squirrel article for more info.
A OS X command line tool to run JavaScript (Prototype) unit tests from the comfort of your terminal.
Recently I came across an article on testing JavaScript outside the Browser, which talks about running tests written in Ruby against your JS libraries.
At the office we loved the idea of being able to run our JS unit tests together with all other (Rails) tests. However, not in the way the aforementioned article suggests.
Now I know the title of the article explicitly says “outside the Browser”, but running outside of a real browser seems a bit pointless to me. I’d rather run them inside an actual browser, as we are currently doing by hand on Safari. And also write them in a format that would allow us to run them by hand on any browser, ie HTML/JavaScript.
Since we’re all on Macs, my Cocoa flags where quickly raised. Especially on the use of WebKit, which, as you might know, powers Safari.
I fired up my favorite text editor and wrote a prototype. Happy with the results I decided to re-write it for real this weekend. Also because I needed something noteworthy to write about on this new blog ;-)
The source is available as either a Ruby gem, or directly from GitHub. To install the gem:
$ sudo gem install Fingertips-headless-squirrel -s http://gems.github.com
Headless Squirrel comes with a command-line tool, called jstest, which you can feed HTML files that run Prototype unittest.js test cases.
For instance, let’s run the Prototype test suite which comes bundled with the Headless Squirrel source code (updated slightly):
$ jstest test/regression/prototype/unit/*_test.html
...................................................................
...................................................................
....F..............................................................
...................................................................
...................................................................
.....................
1) Failed:
testViewportDimensions (Unit test file | Dom | default template | 2009-04-11 15:28) [test/regression/prototype/unit/dom_test.html]:
Failure: NOTE: YOU MUST ALLOW JAVASCRIPT TO RESIZE YOUR WINDOW FOR THIS TEST TO PASS
expected: <50>, actual: <0>
Failure: NOTE: YOU MUST ALLOW JAVASCRIPT TO RESIZE YOUR WINDOW FOR THIS TEST TO PASS
expected: <50>, actual: <0>
Finished in 18.127608 seconds.
356 tests, 2246 assertions, 2 failures, 0 errors
That should look familiar to people using Ruby’s Test::Unit.
I haven’t added a Rake task helper yet, but the following should get you going for now.
namespace :test do
desc "Run the JavaScript unit tests in public/test"
task :javascript do
puts "Running JavaScript tests:"
sh "jstest #{Dir['public/test/*.html'].join(' ')}"
end
end
task :test do
Rake::Task['test:javascript'].invoke
end
Note that the last task does not override the test task that comes with Rails, rather Rake will append the block to the blocks of the existing test task. So when the original task finishes your JS tests will be ran.
I’m pretty happy with the current results. But as you can tell, from the output of running Prototype’s test suite, there’s still a problem, and I’m sure there are more like it.
In this case the problem is that there’s no actual window object (NSWindow) associated with the WebView instance, which is why the poor bugger can’t adjust its dimensions. People shouldn’t be resizing the users windows anyways, so I don’t worry about this problem too much ;-)
As stated earlier, Headless Squirrel currently only works with Prototype’s unittest.js, because that’s the combination we are currently using at the office. However, it should be easy enough to add support for other test frameworks. Let me know if you do so.