Using Instance Variables with Cucumber Steps

Posted on by Michael Orr

I was recently helping a developer test a feature using cucumber.  He was using mostly webrat steps and basic Rails features like dynamic finder methods. He knew that he could use local variables in steps but didn't know he could use instance variables to simplify the process of finding all of the objects he needed to test.

Let's say you need to test for a value that you store in the database but you can not find on any page in your application. Perhaps you needed to have setup several users and test that one particular user has a valid internal GUID set on it.  You could just select the user into a local variable by a known label to test it.

Then /^the test user should have a valid guid$/ do
  user = User.find_by_login("test_user")
  user.guid.should =~ /\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}/
end

This works pretty well for a time, but it closely couples the test to the actual login used to create the user.  The step can't be used to test a user with any other login value and you may find the need to change your test user's login when writing a new test.  It's never fun to have to rewrite a bunch of your tests to for something minor and you don't want to clutter your step definitions with tiny variations on the same test. The example step above also has to pull the user object from the database every time. Extra find methods running  all over your test suite can defintely slow it down.

If you assign an instance variable to an object in the "Given" step when you create the object, then you can test that object's values in a "Then" step later on.

Given /^a user "(.+)" with password "(.+)"$/ do |login, password|
  @test_user = User.create(:login => login
                           , :password => password
                           , :password_confirmation => password)
end

You can test the values of the instance variable in a later step.

Then /^the test user should have a valid guid$/ do
  @test_user.guid.should =~ /\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}/
end

Now you could give your test user any login value that you want.  Smart usage of instance variables can add flexibility to the steps in your test suite and cut down the time it takes your tests to run.

 
comments powered by Disqus