Cucumber Tables + Factory Girl = Crazy Delicious

August 1st 2009

Consider the following cucumber step:

Given /^the following "([^\"]*)" exist:$/ do |type, table|
  singular_name = type.singularize
  table.hashes.each do |hash|
    Factory(singular_name.to_sym, hash)
  end
  if Object.const_defined?(singular_name.classify)
    (class << singular_name.classify.constantize ; self ; end).instance_eval do
      define_method(:find_by_cucumber_handle) do |x|
        find(:first, :conditions => {table.headers[0].to_sym => x})
      end
    end
  end
end

Sure, no surprises. We use factorygirl to pump out a ton of models in the table. But what’s with all that metaprogramming crap in the middle? #find_by_cucumber_handle?


    # features/support/paths.rb
    # ...
    when /the "([^\"]*)" page for "([^\"]*)"/
      path = $1
      parameter = $2
      constant = path.capitalize.classify
      send (path.gsub(/ /, '_') + "_path", constant.find_by_cucumber_handle(parameter) )
    # ....

Which lets you do things like:

Background:
  Given the following "users" exist:
    |username|
    | alex   |

Scenario: User logs into site
  Given I am not logged in
  When I go to login
  And I fill in "login" with "alex"
  And I fill in "password" with "password"
  And I press "Login"
  Then I should be on the "user" page for "alex"
  And I should see "Logged in as alex"

Only for every model ever.

Tasty!

For extra credit, use the splat operator + regex-fu so you can do /user/products/commentaries/etc as the cucumber step:

Then I should be on the “user” “products” “commentaries” “etc” page

blog comments powered by Disqus