I’ve tried Cucumber for a few projects a couple of years ago and am looking to give it another go. I don’t really need another “Beginning Cucumber” article. Instead, I’d like to see some actual uses in the wild—one’s that other Cucumber users would consider idiomatic and antipattern-free.
So, in your opinion, what are the best examples of actual Cucumber specs in large projects?
You can read diaspora’s cucumber tests. It’s a pretty big project so I think you can learn something from it.
You can read the features of Cucumber itself, the guys should know what they are doing:
This isn’t a direct answer, but I disagree with a premise in your question but have a solution, so I’ll give my opinion anyways.
one’s that other Cucumber users would consider idiomatic and antipattern-free
This statement, I think, is unfortunately impossible to satisfy.
Here’s Brandon Keepers of CollectiveIdea taking a commonly held position that you should strive towards generic, reusable steps, which makes sense from a general “Don’t Repeat Yourself” perspective.
However, here’s Aslak Hellesøy, the author of Cucumber, taking an also commonly held (but mutually exclusive) opinion that you should strive towards scenario-specific steps, which makes sense from the perspective of “why Cucumber at all?”
After years of using Cucumber in both styles, and considering the above dilemma, these are my conclusions:
- Reusable steps become a maintenance nightmare as you need to support more complex step definitions while also avoiding naming conflicts.
- Scenario-specific steps are preferred for readability and simplicity, but also become a maintenance nightmare just due to naming conflicts.
So, I’ve decided that Cucumber is currently broken, and plain Capybara on top of your favorite unit testing framework is the most flexible.
Cucumber could, if they chose, add scenario contexts, feature-specific scenarios, scenario namespaces, etc such that you could scope your scenarios somehow – by feature, user role, whatever makes sense – and greatly reduce naming conflicts to make scenario-specific steps truly viable. At that point, I think there would be a clear stylistic winner. Until then, there will always be this tension of needing to abstract your steps to avoid naming conflicts vs wanting to keep them scenario-specific for simplicity & readability.
An alternative project that attempts to address these shortcomings is Spinach, but the project isn’t all that active. See my comments here about an evaluation of Spinach vs Cucumber.
I was looking for Cucumber projects as well. And actually there is wiki page on Cucumber’s repository with a list of such projects (not all of them are still using Cucumber though):
Projects using Cucumber:
- OERPScenario (linked to OpenERP)
- Rails directory
- Heroku Suspenders
Update: As mentioned by Ivailo Bardarov, they use websteps which is a bad practice at present. Just look at this as a reference to see good features and not steps!
Update 2: I think off-late, I learned a lot from following cucumber features provided with paid version of Object on Rails book. The source code is not open-source so I cannot post it here or could not find a link to it.
My preferred way is to keep feature language close to domain / business language rather than specific steps or filling in form. So instead of having something like this in my features:
When I fill in "Name" with "XYZ
I will have my feature say:
When I create a project: | name | | xyz |
And then my step would have, the code to click the link, parse the table and fill the relevant form field etc.
We’re using Cucumber on my current project for a web app redesign, but it’s not open source, so I can’t offer an actual set of features and steps.
I will say that we’ve been heavily inspired by the Page Objects pattern in these two samples. We’re in the middle of heavy UI refactoring with out UX team. Using Page Objects has made adapting the tests to those changes reasonably simple.
I wish I could post the ones from our corporate repo (massive internal web app for a Fortune 500).
The best in the wild is probably Wikipedia’s tests:
You really need to abstract with page objects. Even then when your app gets past 30 screens of input your tests get hard to abstract.
I have an experimental way of quickly abstracting common paths without cycles; should probably clean it up and send it as a pull request to Cheezy: https://github.com/cheezy/page-object
A common issue with large projects is that the Cucumber features take a lot of time to write.
So there are a number of strategies involved:
If you are using Cucumber to describe a legacy system, you get decent acceptance test coverage via cucumber and capybara, and then refactor your cucumber step definitions.
If you are unit testing properly, use Cucumber to only describe the happy path of your app, or only essential non-happy paths. Get coverage with RSpec (or Xunit of choice).
The key issues with Cucumber is that the features should be describing functionality at a very high level. You need to make your step definitions DRY and reusable, and I am a fan of redirecting step definitions to keep the stakeholder-interesting features concise and to the point. Though I think that point can be a bit contentious.