samhuri.net/posts/2007/06/testspec-on-rails-declared-awesome-just-one-catch.md
Sami Samhuri 007b1058b6
Migrate from Swift to Ruby (#33)
Replace the Swift site generator with a Ruby and Phlex implementation.
Loads site and projects from TOML, derive site metadata from posts.

Migrate from make to bake and add standardrb and code coverage tasks.

Update CI and docs to match the new workflow, and remove unused
assets/dependencies plus obsolete tooling.
2026-02-07 21:19:03 -08:00

2.8 KiB

Title Author Date Timestamp Tags
test/spec on rails declared awesome, just one catch Sami Samhuri 14th June, 2007 2007-06-14T07:21:00-07:00 bdd, rails, test/spec

This last week I've been getting to know test/spec via err's test/spec on rails plugin. I have to say that I really dig this method of testing my code and I look forward to trying out some actual BDD in the future.

I did hit a little snag with functional testing though. The method of declaring which controller to use takes the form:

use_controller :foo

and can be placed in the setup method, like so:

# in test/functional/sessions_controller_test.rb

context "A guest" do
  fixtures :users

  setup do
    use_controller :sessions
  end

  specify "can login" do
    post :create, :username => 'sjs', :password => 'blah'
    response.should.redirect_to user_url(users(:sjs))
    ...
  end
end

This is great and the test will work. But let's say that I have another controller that guests can access:

# in test/functional/foo_controller_test.rb

context "A guest" do
  setup do
    use_controller :foo
  end

  specify "can do foo stuff" do
    get :fooriffic
    status.should.be :success
    ...
  end
end

This test will pass on its own as well, which is what really tripped me up. When I ran my tests individually as I wrote them, they passed. When I ran rake test:functionals this morning and saw over a dozen failures and errors I was pretty alarmed. Then I looked at the errors and was thoroughly confused. Of course the action fooriffic can't be found in SessionsController, it lives in FooController and that's the controller I said to use! What gives?!

The problem is that test/spec only creates one context with a specific name, and re-uses that context on subsequent tests using the same context name. The various setup methods are all added to a list and each one is executed, not just the one in the same context block as the specs. I can see how that's useful, but for me right now it's just a hinderance as I'd have to uniquely name each context. "Another guest" just looks strange in a file by itself, and I want my tests to work with my brain not against it.

My solution was to just create a new context each time and re-use nothing. Only 2 lines in test/spec need to be changed to achieve this, but I'm not sure if what I'm doing is a bad idea. My tests pass and right now that's basically all I care about though.