I recently resumed work on a Rails project I started a few months ago only to find that some of the functional tests that Rails generated for some scaffolding code were failing. These tests were failing on a fresh checkout from Subversion, so it was obvious that I’d neglected to run the functional tests before at least my last checking a few months prior. That of course was a problem, but now I’ve corrected that by figuring out a better way to ensure that I can always run the tests.

I spent all day yesterday working on functionality other than the one controller that was failing. I saw the failing tests but decided that since they were on controller code that was generated by scaffolding, I would let them go. I actually thought perhaps the tests were generated wrong, but of course that was not the case. Since I’m now using autotest, I decided I’d better figure out why those tests were failing because I just couldn’t bare to see those failures flashing before me all day while I’m working (and I didn’t want my little project to suffer from the Broken Window theory).

I started by looking at the failures, of which there were four (the real controller name has been changed to protect the innocent).

1) Failure:
test_create(SomeControllerTest)
[/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/assertions/response_assertions.rb:26:in `assert_response'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/assertions/response_assertions.rb:18:in `assert_response'
test/functional/some_controller_test.rb:59:in `test_create']:
response to be a <:redirect>, but was <200>

2) Failure:
test_edit(SomeControllerTest) [test/functional/some_controller_test.rb:72]:
is not true.

3) Failure:
test_show(SomeControllerTest) [test/functional/some_controller_test.rb:40]:
is not true.

4) Failure:
test_update(SomeControllerTest)
[/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/assertions/response_assertions.rb:26:in `assert_response'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/assertions/response_assertions.rb:18:in `assert_response'
test/functional/some_controller_test.rb:77:in `test_update']:
response to be a <:redirect>, but was <200>

4 tests, 10 assertions, 4 failures, 0 errors

So I started by looking at the test for Failure 1 to see if there was anything odd going on. I noticed that the test was trying to create the model without any of its properties. So I went to the code and sure enough, if a save was successful it was redirecting and if not it would render the new action. Since no properties of the model were being passed to the controller, no model was being created. A quick modification to the test to pass in the required properties and it was passing.

At first I hard-coded these properties into the test, but then I took at look at the fixtures and decided I should be using those. It was a good thing I did, too, because it turns out the remainder of the tests were failing due to bad fixture data. The first two fixture entries were missing some properties that, after the original creation of the model, were added as required properties. So I added the missing properties and, to my pleasant surprise, the rest of the failing tests passed.

So the moral is: keep your fixtures updated as you modify your model, especially if adding required properties. AND, more importantly, always run your tests and you’ll know right away as soon as you break something (at which time it will be much easier to figure out what caused it).