In preparation for two Ruby on Rails workshops in Sydney, Australia in a few weeks, I’ve discovered a few testing tidbits.

Test Timer

Some of my tests were very slow, but I didn’t know which ones were the slowest. I wrote a minor hack to Test::Unit that prints a report of how long each test takes to run.

Require it after Test::Unit in any test and you’ll know what you need to work on.

sudo gem install test_timer

require 'test_timer'

# Output looks like this
0.857 test_bar_graph_set_colors(TestGruffBar)
0.909 test_wide(TestGruffArea)
0.982 test_many_areas_graph_small(TestGruffArea)
1.081 test_set_legend_box_size(TestGruffBar)
1.114 test_many_datapoints(TestGruffArea)
1.152 test_tall_graph(TestGruffBar)
1.191 test_wide_graph(TestGruffBar)
1.744 test_area_graph(TestGruffArea)
2.119 test_custom_theme(TestGruffBar)
2.652 test_bar_graph(TestGruffBar)
4.511 test_y_axis_increment(TestGruffBar)

Faster ActiveRecord callback tests

I noticed that some very simple tests were taking more time than they should. I looked into using Mocha but couldn’t find a good way to hook into the saving process.

It turns out that you can just call the callbacks directly without hitting the database at all:

article = Article.new(:title => "Soggy Bacon")
article.send(:before_create)

assert_equal 'soggy-bacon', article.permalink

Test Rails Layouts Alone

I’m using Test::Rails from ZenTest for a few projects.

I wanted to be able to test layout templates apart from their contents. But Test::Rails::ViewTestCase looks at the name of the test and the name of the test methods to find what controller and template to use.

The solution was to create a temporary controller for layouts so they could be tested alone.

# Fake controller so bare layouts can be tested
class LayoutsController < ApplicationController; end

class LayoutsViewTest < Test::Rails::ViewTestCase
  # Tests layouts/application.rhtml alone
  def test_application
    # Set instance variables for the template
    assigns[:article] = Article.new(:title => "Soggy Bacon")
    render
    assert_...
  end
end