From what I understood this morning, the concern Steve had was to be able to use the acceptance specs as a communication tool with the clients, whether directly (the clients read it) or indirectly (the clients do not read it).
The concern from me (at least) is the maintainability of the Cucumber steps. Here are some example:
- Projects where there were so many cucumber steps that it became hard to figure out what each step did
- Projects that tried to be too DRY with the steps the regexps became difficult to handle
- Projects where a lot of set up was required, and the steps to create the users like became long and too descriptive (
Given an active user exists that last logged in 2 years ago
) - Projects whose Cuke steps shared World-wide variables (
@project
) that were used across steps
For me, using Capybara directly solves this. But, I must agree that only developers can read them. Why not have the best of both worlds?
Given this rspec file:
feature 'User can disable their own account' do
background do
given 'a user Bob exists' do
@user = FactoryGirl.build_stubbed(:activated_user,
username: 'Bob')
end
end
scenario 'Disables own account' do
given 'I am logged in as Bob' do
sign_in_as @user
end
when 'I go to my account page' do
visit account_path(@user)
end
when 'I click on the button to disable my account' do
click_button 'Disable my account'
end
then 'I should see the message that I am logged out' do
within '.flash-messages' do
should_see 'You have been logged out. We will miss you.'
end
end
end
end
The output would contain something like this:
Given I am logged in as Bob
When I go to my account page
And I click on the button to disable my account
Then I should see the message that I am logged out
expected page to contain 'You have been logged out. We will miss you.' but
it did not
My two cents:
Aside from the global variables, what ultimately added complexity in Cucumber is the regex. When doing BDD (presumably with a client), I think the two indispensable components that we are looking for are:
.feature
files. Based from Steve's reasons for choosing Cucumber, I suspect that it's really Gherkin that we really want. Basically, we want business analysts (spec/product/domain guy) to articulate specs without dealing with the internals of the app they want us to create.I think it's overkill to use regex in step defs just for the sake of DRYness and being able to accept parameters. Like what Steve said, steps don't have to be as DRY as our codebase. The right way of describing the scenarios should be in declarative way anyway. Ergo, less regex needed.
Gladly, there are already a number of available alternatives to Cucumber that may address our specific needs. Here are my first impressions of each option based on their docs/description:
might
use this internally, but I'm pretty sure that for client-based work, we wouldn't.it has Gherkin. +1!
step definitions are just in this format (easier than regex):
module SomeSteps
step "there is/are :user_count users" do |:user_count|
# some ruby code here e.g. capybara
end
end
You control the scope of specific steps via RSpec.configure, since steps are defined in modules. At the very least, this can easily solve step conflicts.
Feature: Some Feature
are either in that associatedSomeFeature < Spinach::FeatureSteps
class, or in theinclude
-d modules. No surprises. Less chances for conflict.private
-ize methods,include
Modules. Whatever floats your boat.Personally, I would like to try out Spinach first, simply because it was borne out of the same frustration we had for Cucumber (step definitions). This is the tool that satisfies our minimum requirements.
What do you think?
(This discussion is worthy of a tech talk, a blog post, and/or topic for the upcoming meetup.)