Tuesday, May 25, 2010

Why Do I Like Spec-Style Unit Tests?

As I've written about earlier I've been spending some time lately learning Scala. A side effect has been learning and using two test frameworks I haven't used before; ScalaTest and Scala Specs. Both offer what I think of as a spec style of writting tests. That is, tests along the lines of:

"A unit under test" should {
  "be tested by specs like this" in {
     // Code  for the first actual case
  }
 
  "and like this one" in {
    // Code for the second test case
  }
}

where a string is used to tell what's under test, and strings are also used to give each test case a name. In contrast "traditional" [J|N]Unit tests use method names to give each test case a name, and either don't point out the unit under test or use a class name for that.

The spec style of testing, I find, makes a test first workflow feel more natural, and makes my red/green cycles shorter, leading to more interaction between tests and code, and to better coverage. Very nice :-). I noticed this after using ScalaTest for a while, and found the same later when I started using Specs. Somehow both these frameworks gently nudge me towards a more clean TDD workflow.

I think the reason is that the unit under test is very explicitly named and that the test cases are named with strings rather than method names. Using a strings rather than method names makes me write longer names, and makes me write names that form full sentences when combined with the unit under test and the 'should' from the 'should' method. As in the example above which reads as "A unit under test should be tested by specs like this and like this one". The full sentences turn the tests into something a bit closer to specs, or rather, for me, the full sentences turn the tests into the place where I think about what exactly I want my classes to do, which makes it natural to write them first. On the other hand the natural language of full sentences makes me a little more aware of details, and therefore makes each test smaller and more focused which is what makes my red/green cycles shorter when using the spec style.

Smaller red/green cycles and a more test first approach has the usual benefits of turning the test into a design tool that leads to low coupling and high cohesion in the code under test, of creating high test coverage, and of catching coding bugs very early on.

That's why I like the spec style approach to unit testing.