This post is part of our Practical Cucumber series.
Given a product named "Some Product"
What’s wrong with this? Not only does it communicate nothing about how this feature works to the end user, it defines very specific steps that will likely only be used in this scenario.
Cucumber steps are meant to be reused. If you are defining steps that are only used once, you’re probably doing it wrong. You should eventually get to the point in your app where you rarely have to implement a step in order to write a new scenario.
And I follow "Some Product"
And I press "Add to Favorites"
Then I should see "Some Product"
The first step comes from factory_girl (which we’ll post more about), and the rest are defined in the web_steps.rb.
While this version is longer and more verbose, it is infinitely better. It clearly communicates how the enduser will experience this feature and required no code, allowing you to focus your programming prowess on the implementation.
This is great advice, and I need to follow it more.
One problem I frequently run into, though, is trying to keep view implementation details out of my features and into my steps. I frequently have a problem where I define some things about the view that a designer then changes. These aren’t important changes either. For instance, what if the designer doesn’t like “Add to Favorites” and changes it to “Favorite”? Then the build breaks because of a wording change, but the feature should be a description of functionality, not a description of the view implementation.
I believe I read a post from Bryan Helmkamp that recommended writing features more like your first example. It pushes view implementation details into the steps and keeps the features as descriptions of the business requirements, not of the interface. The test may still break if wording changes (unless you’re smarter and press buttons or click links by id instead of label) but they will break in the steps instead of the features the stakeholders see.
This strategy does make you write a lot of steps, but I try to keep these organized and continue to refactor them as needed.
Can you comment on how to reconcile these different strategies?
Tony Hillerson: Thanks for sharing your struggles. We have definitely felt your pain.
However, in many cases, the text on the page is actually significant. As developers, we tend to diminish the importance of design and words, but to many clients, the form is equally as important as the function. It is all part of the acceptance criteria. The overhead of having to change the text every once in a while is insignificant compared to the overhead of writing custom steps for every scenario, just in case the text ever changes.
If it is something that changes frequently, and the cost of maintenance becomes too high, then abstract it in a way that doesn’t cause you to incur technical debt with every new scenario. The way that the built in web_steps.rb handles paths is a perfect example. There are several steps around navigating to the correct page, and they delegate to one method to determine the actual route.
We will be posting soon on a way we’ve used this pattern to scope to elements on the page.
This single post was one of those ‘click’ moments for me, where cucumber finally started to make so much more sense.
if you are going to test a table, at that time how ll you write scenarios?
Another approach to keep your cucumber steps safe regarding text changes is to use the translation framework throughout your application to unify the access to any text passages. Then in your step definitions you also use the translation key to let capybara always click the correct button etc.
Cucumber scenarios should not break because of a changing the text.
@Dominik That’s a fantastic idea! I’ll be sure to do that moving forward. You’re absolutely right that Cucumber shouldn’t depend on specific text content. It makes for brittle tests and I’ve run into that very problem far too often. Thanks!
Yeah this is exactly what the cucumber developer says not to do. I would not do this.
Yeah, we’re in disagreement on that point. We actually find that using web steps with good markup make features more maintainable. We’ll be blogging more about how we think to do it well.
I disagree with approach above, the first feature is quite abstract and is not coupled with implementation (link names, button captions), and “improved” feature is coupled with this kind of knowledge, just one question: what happen is someone rename “Favorite” link to say “My Selected Products” or rename button “Add to Favorites” to “Add to my favorites”, whatever … You’d have to look all over the features code to fix this issue, while this kind details should encapsulated in domain classes not in features files ..
Alexey: For stuff that changes often, take a look at the selectors file in what is now the sadly-named cucumber-rails-training-wheels It is an approach I like a lot.
Why I like using text for much of our tests is that it is what the user sees. I want to be testing their flow, not a highly abstracted version.
As far as step reuse, I think that is one of the best features of Cucumber. In our experience, features are more stable when you don’t have tons of custom steps. Reuse is key.
Thanks for you thoughts though. I know we’ll never be on the same page with everyone.
Tegs: декоративная штукатурка сходненская декоративная штукатурка малярные работы дизайн стен декоративная штукатурка.