Just A Summary

Piers Cawley Practices Punditry

Getting the Rspec religion 3

Posted by Piers Cawley Sun, 26 Nov 2006 08:52:00 GMT

I’ve been eyeing the rspec and rspec on rails packages and thinking I should give them a go.

To my eye at least, something like:

context 'Given a published article' do
  fixtures :contents

  setup { @article = contents(:published_article) }

  specify 'changing content invalidates the cache' do
    @article.body = 'new body'
    @article.invalidates_cache?.should_be true
  end
end

context 'Given an unpublished article' do
  fixtures :contents

  setup { @article = contents(:unpublished_article) }

  specify 'changing content keeps the cache' do
    @article.body = 'new body'
    @article.invalidates_cache?.should_be false
  end
end

reads far more fluently than the equivalent Test::Unit based tests:

class CacheSupportTest < Test::Unit::TestCase
  fixtures :contents

  def test_changing_published_article_invalidates_the_cache
    art = contents(:published_article)
    art.body = 'new body'
    assert art.invalidates_cache?
  end

  def test_changing_unpublished_article_keeps_the_cache
    art = contents(:unpublished_article)
    art.body = 'new body'
    assert ! art.invalidates_cache?
  end
end

So, I installed everything and started to work on a new class in Typo using rspec. Rather annoyingly, this seemed to break the current test suite, so instead of working on my new model class, I set to porting the existing suite.

And, on about my third test suite, I found what I think is a bug in the suite. I’m not sure it’s a bug, because, the way the test is written (by me, I admit it), masks the intent quite dramatically. I’m also finding that the freedom to name specifications and contexts in English rather than method_names_that_go_on_for_ever is forcing me to come up with much more useful descriptions of what I’m testing. I find myself working on making the spec runner output read reasonably well as English, and doing that casts light on what is and isn’t being tested.

I’ve known for a while that Typo’s test suite is, um, spotty, but the porting process is really helping me get familiar with what’s being tested. I’m half tempted to start adding extra specs as I go, and if I could work out how to keep the existing tests working while I did it, I would, but my priority for now is to get to the point where I can check the specs and be confident that the new specs are no worse than the old tests.

Because I’m much more confident that I know what the specs are doing, I’m also confident that it won’t be hard to revisit them to help specify typo’s behaviour better. I’ll just have to give myself the discipline of beginning each coding session with half an hour of fleshing out the specifications before I get back to adding behaviour.

Comments

Leave a response

  1. Avatar
    Daniel Berger 10 days later:

    I’m just not sold on that style of testing. The statements may be more english-like, but what it gains in verbs it loses in verbosity.

    Looking at your two examples, I prefer the Test::Unit approach. :)

  2. Avatar
    Piers Cawley 11 days later:

    Personally, I think verbosity, nay prolixity to be a virtue. Especially in the case of tests.

    As I’ve been porting Typo’s unit tests to specs, I’ve certainly been finding that the

    context "Given whatever" do
      setup {...}
      specify "something should be true" {...}
    end

    rhythm of working gets me thinking along helpful lines. Also, I’ve found myself splitting single tests into a context and a set of specifications, and those cases are definitely more readable.

  3. Avatar
    David Chelimsky 27 days later:

    It’s great to hear that you’re getting some mileage (or kilometer-age???) out of rspec! Sorry to hear that you feel forced to convert your entire suite, though I’m sure it’s a great exercise and look forward to reading more about your observations.

    The problem you describe (of only being able to run one or the other) has gone away w/ the current version of rspec_on_rails. If you don’t want to upgrade right now, just clean out the init.rb file. The stuff it requires should get required by your spec_helper.rb instead (probably already does). That way rspec only gets loaded when you’re running specs. When you’re running tests it doesn’t, so no conflict.

    Cheers, David

Comments



Just A Summary