I had really poor experiences with Cucumber. The annoyance with Cucumber comes nearly all from a case of indirection. If devs are writing the Cucumber tests and then writing all the regular expressions to implement the steps, then you often wonder why the heck you’re not just writing tests in Ruby. SO WHY DON’T WE JUST WRITE RUBY AND SKIP THE INDIRECTION?!?!?!
On a recent project however, my anchor spent the first 3-4 weeks with a lot of hands-on time working with the PM to get the PM to write stories in Tracker with multiple scenarios in the “Given… When… Then…” syntax. We then paste it directly in to a .feature file and start defining the steps. We don’t try to reuse steps very much. This means steps.rb becomes a type of dumping ground and you just have to let that go. WHAT YOU HAVE TO DO is not put much in the steps.rb and build up a “language” that lives in your helper files which are well maintained and clean. This is the key. Some rules of thumb: steps should be short, one line is best. No Capybara in your steps, so don’t say “visit new_user_form” or “page.should have_content(…)” in your steps, put that in a helper method or custom RSpec matcher that is like “open_user_form” or “widget.should have_success_message” respectively. This way, when you look at the step because you are walking through the layers of indirection, it’s really clear what’s going on, and really straight forward to update when your UI changes – because it will.
You could (and should) do a lot of the same things in plain-Jane Capybara specs, it’s just good practice to be pulling up this domain specific language. The value of Cucumber comes in when a PM is writing the specs. It’s time consuming for that PM though. In an hour long story writing session, we get through writing about three stories. It works well for our team of 4 engineers and 1 designer. I don’t know that it would scale well to a team of 8 that needs more stories each week. We also take our Cucumber features and publish human readable documentation via Relish, so future devs or PMs could have some expectation about our intentions.
If only coders are reading and writing the specs, forget Cucumber. If non-coders are actually participating, then Cucumber starts to make sense. I find that we basically end up paying the specification cost up front. I know it works because in our team of 4, we rarely disagree on estimates (we always throw the same number). The payoff is that on this project we don’t have to turn to our PM for clarification nearly as much as I’ve had to on other projects.
The caveat though is that payment of cost up front. If you’re writing ten stories a week and throwing eight away, you’re wasting a lot of time and energy writing stories. Stories are fairly stable on projects where we’re doing re-writes and thus the feature set is known, or where the feature set is VERY well defined (as may be the case when cloning functionality inan existing product). In most other projects, the backlog gets shuffled around a good bit as things get released, users give feedback, and company priorities shift. In this later case, you want to put in some minimal effort upfront on story writing and pay the rest of the cost during IPMs and once the story is picked up by a pair. Cucumber has its place, it’s just not every place.