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


One note on the 'Faster ActiveRecord callback tests': this only works if you have:
class Thing < ActiveRecord::Base
def before_create
#do something
end
end
...defined in your model. If you use:
class Thing < ActiveRecord::Base
before_create :some_method
private
def some_method
# do something
end
end
...it doesn't seem to actually call all the before_create methods. Anyone know anyway around this?