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
Thank you Ramon, for suggesting what might be a good compromise. I need to think about it more.
Here is one thing that cucumber buys, that his compromise might now address: A change in the requirement produces a diff in the spec that can be associated with the changes made to support that, all legible from reading the git log. When you are going back over the history of a feature, it does help to see clearly how the spec was changed at some point vis a vis other related changes. The more the specification looks like code, the less easy this is to do. If the cucumber is essentially a comment or a label then the requirement could be changed or the test could be changed without necessarily updating the comment and it would be hard to tell if the spec was supposed to change or if the test was changed for another reason solely from looking at the git log/diff.
I am also thinking about how a tool like tracker or our own version of tracker, would better integrate with the source control and timekeeping system. Cucumber provides a valuable hook into the source code for higher level changes. I know that sounds vague.
To a couple of your points following up keikun17:
I think the general idea is not to "reuse" or refactor your cucumber steps to make them dry or whatever. I think in cucumber steps, it is permissible in some cases to not be so dry or at least its okay to repeat yourself as soon as dryness becomes a problem.
I think the performance penalty during setup comes from the fact that you need a database cleaner because transactions do not work across the server/client boundary of capybara/rack, esp when javascript gets involved and capybara launches a browser. This means rebuilding database state from scratch. However, I think this is amenable to technical improvement and solution and we may be able to make a contribution to the state of the art.
I agree sharing world-wide variables is bad. We ought to be able to avoid this.
As a company, we need a process and there is a role for someone to create the cucumber working directly with the client. Right now I am filling that role but eventually it will be someone else, maybe even one of you. There are other ways to do it such has having specification documents that live outside of source control, but these have a lot of variability in format and quality and it is hard to say when a feature is "ready" to be estimated or to start developing. Imagine you are in my position and you are writing the spec for your associates to follow in developing features. How would you express it? You can't think in code, that is too involved. Anyway, its not up to you, you're not going to do the development, just write the spec. What are you going to write? I'll bet you write something like cucumber.
I think the cucumber level of analysis leads to a certain confidence factor that the feature has been thought through enough that it is ready to enter the backlog. Without cucumber we would need to become very good at spec-writing and maintaining and versioning those documents separately and frequently problems would remain buried until work begins and then estimates blow up. Or worse, we rely on the customer's "specs" that are almost never detailed enough or consistent. Either way, quality will suffer.
Ergo, someone is going to write cucumber.
I think Cucumber has an important role in the process and is a powerful tool for formalising requirements and bridging the gap between developers and clients. Now, I know it takes about 20 hours of me writing cucumber with a client to lay out 2-4 months of work for a pair. Ergo, if we were fully booked with 5 pairs, I could expect to spend approximately 30% of my time writing cucumber with clients. If I cannot afford to spend that much time or we want to scale beyond 5 pairs, I need to hire someone. I don't want to become a bottleneck, so it has to be a job that someone else can learn to do, and soon. I have no grasp on how long the spec process would take without cucumber or what the other gotchas are. I can train someone sufficiently able to do this job with cucumber. The only other process I know is something like what HH does and I am curious to know which process our team prefers.
I know this is a process/tool thing. Cucumber is a tool that facilitates a process. Until now it is the best tool that I have seen. If you want to propose a replacement, or even invent one, then we should address how the replacement fits into the process and what the implications will be.