{ |one, step, back| } 1 of 1 article WikiSyndicate: full/short

Test VS Behavior   25 Oct 05
[ print link all ]

This article was sparked by a some conversations and discussions at RubyConf 2005.

Test VS Behavior

It seems fashionable these days to say that Test Driven Development is not about testing at all, but rather about (fill in the blank), where the blank can be filled with “design”, “behavior” or “specification”. At RubyConf this year, one of the “informal” discussion sessions around the pool area drew a large crowd of people to discuss this very topic.

The RSpec ruby library (from Steven Baker, Dave Astels and Aslak Hellesoy) is a replacement for Test::Unit. Its main focus is to change the terminology surrounding the whole TDD approach to software development. I think this is key … it is not changing anything fundamental about the processes, it is focused upon the words we use in describing the process. But don’t be fooled into thinking this is a matter of semantics only, for the very words we use to describe something shapes our thought processes about the thing we are describing.

BDD, or Behavior Driven Development, is an attempt to improve TDD (Test Drive Development) by emphasizing the behavior specification nature of traditional TDD. By freeing TDD from its test bound terminology, we avoid some of the preconceptions (e.g. “Tests? Yuck!”) that developers bring to the table when discussing TDD.

So What’s Different

So, what’s the real different between RSpec and Test::Unit? Compare these two code snippets. First the “test” version:

  class TestEmptyMovieList < Test::Unit::TestCase
    def setup
      @list = MovieList.new
    end
    def test_size_is_zero
      assert_equal 0, @list.size
    end
  end

And now the specification version:

  class EmptyMovieList < Spec::Context
    def setup
      @list = MovieList.new
    end
    def should_have_size_of_0
      @list.size.should_equal 0
    end
  end

Note: This is from RSpec version 0.2.0 available as a gem from RubyForge. The RSpec guys are currently thinking about using domain specific language for specification. So expect RSpec to change in the future.

We can see that the structure between the tests and the specifications is very similar. Actually, more than similar, they are virtually identical. We just use Context instead of TestCase, use methods with any name rather than those that start with test_, and use object based assertions rather than specific assert methods.

The result is something that reads rather naturally in ruby-accented English. But the functionally is essentially that of Test::Unit, just in different clothing.

Just Semantics!

I hear you saying “But it’s just semantics!” Of course it is. But leave out the word “just”. When conveying meaning, semantics is everything. And one of the important features of Agile developement is to convey the meaning of the code, in the code itself.

Semantics are important!

Is it worth it?

Ok, semantics are important. But is it worth converting all our unit tests into specifications?

Maybe.

I do find the terminology attractive. But I have a large investment in Test::Unit style tests at the moment. And RSpec is still a bit rough around the edges (for example, the error reporting is not quite as mature as Test::Unit’s). And RSpec is going through some major changes at the moment (I mentioned the specification DSL they are playing with).

What would I like to see? One area of specification that current TDD practices tend to be weak in is the specification of preconditions. Preconditions define under what circumstances it is valid to call a method. For example, it may be invalid to call a square root function with a negative argument. Looking at a list of tests (umm … specs), I can’t be sure if negative inputs are not allowed, or if the spec writer just forgot the cover that case.

I’m not ready to switch over to RSpec yet, but it certainly is moving in interesting directions.

What I didn’t talk about

Those of you who were present at the poolside conversation at RubyConf may wonder why I didn’t mention mock objects, since mock objects were a major part of that debate. I see the Behavior VS Test debate to be completely orthogonal to the Mock VS not-Mock discussion. I’ll pick up the mock object debate in another posting, so don’t worry.

 

Formatted: 17-May-08 17:05
Feedback: jim@weirichhouse.org