Reputation: 7083
I'm reading the new version of "Rails Tutorial" by Michael Hartl and, since I'm pretty fond in BDD with Cucumber, I found myself concerned about what the author points out here: http://ruby.railstutorial.org/chapters/sign-in-sign-out?version=3.2#sec:rspec_custom_matchers
In few words the main hassle with Cucumber is that it's impossible to DRY implementation-dependent tests like this:
Then /^he should see an error message$/ do
page.should have_selector('div.alert.alert-error', text: 'Invalid')
end
writing RSpec custom matchers like this:
RSpec::Matchers.define :have_error_message do |message|
match do |page|
page.should have_selector('div.alert.alert-error', text: message)
end
end
Because such a custom matcher must be put in spec/support/utilities.rb and can be called from RSpec integration tests but not from Cucumber step definitions.
Are you positive / what you think about it?
Thank you.
Upvotes: 4
Views: 1664
Reputation: 34327
An example of Jon M's answer, of how you can use RSpec custom matchers in Cucumber:
# spec/support/matchers/http.rb
RSpec::Matchers.define :return_http_success do
match do |actual|
actual >= 200 && actual <= 299
end
end
# features/support/matchers.rb
Dir[Rails.root.join('spec/support/matchers/*.rb')].each { |file| require file }
Upvotes: 0
Reputation: 21096
You can put implementation-dependent or reusable methods, locators to Cucumber World.
Example for your scenario:
# step_definitions/general_steps.rb
Then /^he should see an error message "(.+)"$/ do |text|
within(error_message) do
page.should have_content(text)
end
end
# support/general_helpers.rb
module GeneralHelpers
def error_message
page.first('div.alert.alert-error')
end
end
World(GeneralHelpers)
Here are some articles that refer to this approach:
Upvotes: 3
Reputation: 11705
You can certainly create RSpec matchers and use them in your Cucumber steps - I do this fairly frequently. I just place them in features/support/matchers
and they are instantly available to use in my step definitions.
If you wanted to share them with your RSpec tests as well, you may want to extract them to a separate shared_test
type location, and then you could require
that folder in both your Cucumber env.rb file, and your RSpec spec_helper.rb file, then they would be available in both test frameworks.
Upvotes: 5