DRYing up my functional tests
May 21st, 2007
After my shameful post earlier, Tom Ward put me back on the straight and narrow by suggesting that I try creating a sub-class of Test::Unit::TestCase to avoid overriding send(). Here's my initial stab:
class FunctionalTest < Test::Unit::TestCase
def run(result)
controller_name = self.class.to_s.gsub('Test','')
if controller_name != 'Functional'
@controller = eval("#{controller_name}.new")
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@request.host = "curve21.mymagicalapp.com"
@request.session[:current_user_id] = 1
end
if @method_name.to_s == "default_test"
false
else
super(result)
end
end
end
There's obviously loads to tidy up here, but I now have the functionality in one place that can be expanded easily. With this method, each functional test can still happily have it's own set up and even override the values setup here.
Ultimately I'll add some configuration so this class can be used in other applications, but for now this has DRYed up my controller tests quite a bit and allowed me to specify the shared data:
class DashboardControllerTest < FunctionalTest
def test_should_show_dashboard
get :index
assert_response :success
end
end
Just to clarify, the reason for setting this 'global test data' is that my application is reliant on the URL to identify a user and account on the system. Most of the tests work within that context: Add a user to this account, delete a widget from this account etc etc. As such they just need a test account to work from. I therefore setup the @request.host value to contain one of the URLs from my fixtures.
For the tests where I _do_ need a specific URL (like access control), I can override in the specific method:
class UserController < FunctionalTest
def test_should_not_show_someone_elses_user
@request.host = 'another.magicalapp.com'
get :edit, :id => 1
assert_response :redirect
end
end
Also, as the setup() method is called for a test before each method is run, anything set in that method overrides the base values:
def setup
@request.host = 'another.magicalapp.com'
end
1 Response to “DRYing up my functional tests”
Sorry, comments are closed for this article.

May 22nd, 2007 at 06:53 PM
Stephen, have a look at Test::Rails in the ZenTest gem - it allows you to specify Controller Tests and View Tests. You might find it useful, or at least something to compare your stuff with.