28 November 2012

JavaScript Continous Testing Smackdown

I'm pretty new to serious JavaScript coding. By serious, I mean writing lots of pure JavaScript, as a contrary to putting some JavaScript functions into your <script> block to fizz things up.

I immediately sought out a way to get a smooth TDD development cycle running. I already had a theoretical idea on how to do this - from some of my colleagues who are JavaScript elitists in my book.

As far as I'm aware of, the technique described in this post is THE way to do test driven JavaScript development these days.

So, what will I get from this stuff?

You'll get a terminal which automatically runs your JavaScript tests immediately as you change code. Like Spork in Ruby On Rails, or Infinitest in Eclipse.

Consider the alternative. Having to refresh your browser on every change of JavaScript code. Sound familiar? It's no good; for your quality of life or your aging process (gray hair). Little less your productivity.

Under the hood, these guys passes your JavaScript code to "browser slaves" and shoves the test-results back into your terminal window. I've tried both Buster.JS and JsTestDriver. So, which is the king of TDD JavaScript (in my opinion ofcourse)?

jsTestDriver using watchr

All the code from this blog entry can be found on github. Under a busterjs and jstd branch. https://github.com/finnjohnsen/jstesting

"But hey..? There are other ways to test JavaScript code"

I've noticed, and none I've found are attractive at all.

  • You can refresh your browser and see if your stuff works. You'll have to do this anyway in addition to your unit testing. But you certainly don't want this to be the only way to test your code. It often involved clicking and typing to reach the code you know you want to test. Horrible and unfortunately probably the most common way to do JavaScript development in the world today (I made that up, it's just my guts talking).
  • I've seen set-ups which involves refreshing or triggering the tests from your browser. For example at the Jasmine -site, this is what they document. This is a lot better than the previous bullet point. But we can do better.
  • The Selenium approach: Automate and play back clicks and input-text into your browser. These kind of behavior tests are tightly coupled to html, slow and messy. But they have value as they ensure your site actually works! But it's not what I want for unit testing.
  • Pure Node.js testing. I've tossed this idea, admittedly without really digging into it. Because browsers are too important. Different browsers have different JavaScript implementations, so isolating my tests to the Node.js v8 runtime feels fundamentally wrong.
If you know of other ways, please comment.

Buster.JS or JsTestDriver: My Conclusion

Both frameworks gives you a speedy feedback when working test driven development in JavaScript. However, either will help you all the way - as you may have wished.

  • jsTestDriver requires more patching, hacking and scripting, but works well once you've got it running. You'll probably polish and tune your scripts for quite some time after you've got it running, but you have something working pretty easily. JSTD has wide adaptation and you'll almost certainly find a solution to your problems just by searching around a little. You can have a look at this wrapper, which is suppose to ease the scripting from JsTestDriver. Anyway, check out my sample set up.
  • Buster.JS is a bigger creature. It seems to aim to provide you with some of the pieces missing in JsTestDriver. It provides contrinous/auto testing and an built-in assertion library. These two critical components are what made the installation and set-up of jsTestDriver take a while longer than buster. So check out my sample set up.
I spent about 45 minutes setting up this JSTD project, and 15 minutes on Buster.js. However I've done this before. I suspect I spent at least 2 or 3 times as much the first time.

Buster.JS states on it's website it is under heavy development. It even and uses the word 'unstable' to describe its current state. Leaving JSTD the choice if you can't live with that. Personally I like getting as much set up for me as possible, and I found nothing mentionable when setting up Buster.JS. So I will use Buster.JS on my next green field. I can however be considered biased, one of the authors of Buster.JS work in the same company as I.