Living on the Edge

Overtesting, Who Cares?

Posted on March 18, 2007
As I indicated in a prior post I’m beginning to wrap my head around Rspec and use it in a new project that I’m working on. I recently came across a post where someone had written something similar to the following, indicating a spec for has_many and belongs_to in a model.
context "A Category with fixtures loaded" do
  fixtures :listings, :categories

  specify "should have many Listings" do
    l = categories(:cars).listings
    l.should_not be_nil
    l.should_not be_empty
    l.first.should be_an_instance_of Listing
  end
end

One of the comments to the blog post was critical of this approach suggesting that this spec was validating Rails code and that the author should focus only on code that he / she has written. I’ve seen this argument several times in the past and this issue actually came up briefly in the Advanced Rails Training course in Chicago.

While I agree that you shouldn’t be testing Rails code, that’s not what is going on here. The spec is for the existence of the defined relationships within the model, and that things are wired up properly to enable accessing the relationship properly within the model. If someone were to inadvertently remove the has_many method call in the model the spec would fail, which is exactly the behavior we want.

Secondly, even if we were testing Rails code, I think it’s better to error on the side of overcoverage than to not write tests at all. It is important that developers are not so overwhelmed with the “right” or “wrong” way to do testing that testing is not done at all.

The above code actually comes from a project I’m working on. This blog post aside, if you have recommendations on how it should be done differently, please let me know.

Working with Test::Rails

Posted on March 17, 2007

The past couple of weeks I’ve been digging into Test::Rails from the ZenTest library of tools. One of the main benefits to using Test::Rails is the ability to have separate Controller and View tests. It also includes a lot of test helpers that make the process of testing Views and Controllers much easier. I about gave up on Test::Rails a couple of different times; the docs are a bit sparse and there’s not a lot information on the internet about how to setup and use Test::Rails. I finally happened upon a blog post that gave me a few tidbits of information and got me pointed in the right direction.

The Test::Rails package comes bundled with ZenTest. So let’s go ahead and get that installed first:

gem install ZenTest

ZenTest depends on the hoe and rubyforge gems. Be sure to include those dependencies as well.

ZenTest is a collection of four different testing helper packages. I’m not going to go into detail on the other packages, but I encourage you to investigate them, especially autotest – something I can not live without these days.

Now that we have ZenTest installed, we need to hook Test::Rails into our existing testing framework. To do this we need to require the test/rails file which pulls in all of the other stuff needed to work with Test::Rails:

In the test/test_helper.rb file, add the following line, just before you require test_help. The top of my test/test_helper.rb file looks like the following:

ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require 'test/rails'
require 'test_help

If you’ve read the Test::Rails rdoc files, you’ll see that you’re instructed to reopen up Test::Rails::TestCase in place of Test::Unit::TestCase. If you do this you will likely experience a lot of problems with your unit test, unless you change them to inherit from Test:Rails::TestCase instead of Test::Unit::TestCase. Personally I just leave my unit tests as is and leave the rest of my test/test_helper.rb file alone. Since Test::Rails::TestCase derives from Test::Unit::TestCase everything will continue to work properly.

At this point you can continue on with the rdoc documentation on Test::Rails, specifically starting with the section title “Writing View Tests”.

If you are attempting to convert your existing Functional tests into Controller and View tests, pay particular attention to the format of the sample Controller and View tests in the rdocs. Even better, get the VIC plugin written by Geoffrey Grosenbach. It contains three generators for generating the basic structure needed for Views, Integration, and Controller tests:

./script/generate integration_test JournalStories
./script/generate view_test Journals index edit new
./script/generate controller_test Journals index edit new

The nice thing about using Test::Rails is that you don’t have to convert everything wholesale. I still have some of my tests as functional tests, and others as Controller / View tests. Over time I will likely convert everything.

One thing lacking from the Test::Rails package is Helper tests. There is a Helper Test plugin available by Geoffrey Grosenbach and a great tutorial to go along with it.

Test::Rails also comes with a number of helpers that make testing a lot easier. Check out this Test Cheatsheet for a list of enhancements.

I really like the separation that Controller / View tests. Prior to using Test::Rails I always had this crazy suspicion that I was missing something. Now with clean separation I feel a lot more confident and have tests that are a lot more focussed.