Skip to main content

Why I like Cucumber (beyond BDD)

There is a sentiment in software development that if you do not have a working BDD practice then Cucumber is just unnecessary overhead. I understand this position, but I disagree, based on my own experience and my own practice. I find Cucumber is particularly valuable in automated browser tests.

I've been using Cucumber for automated browser tests at work just about every day for the last six years or so. At the same time, I have never worked with a full-on BDD team. Beyond BDD, here are three aspects of Cucumber I find particularly valuable:

  • Cucumber creates a low barrier to entry for anyone at any time to contribute and understand the project.
  • Cucumber's Given/When/Then syntax provides a design guide particularly well suited for browser tests, especially using "When" in a particular way.
  • When a test fails, Cucumber provides a plain-English description of what the test does that may not be immediately apparent from the code or the nature of the failure.

I tend to write browser test suites of significant size and scope, whose working life extends to years. Over the course of years, people will join the project and leave the project, people will have various levels of engagement with the test suite. Cucumber allows someone new not only to quickly grasp the nature of the tests, but also the nature of the project itself. Well-written Cucumber Scenarios are an effective way to describe the behavior that the user sees. I've used Cucumber Features to get interns started, I've used Cucumber features as a starting point for developers familiar with other languages, and I've used Cucumber features to explain current function to people on the team not involved in the day-to-day development work.

I also value Cucumber as a design guide. Of course a Given step represents "setup", a condition that must be in place for the test to be meaningful. And of course a "Then" step should always contain an assertion about the final state of the application being tested. But I think that the "When" step has a particular meaning for browser tests that may not be true for other kinds of testing.

End-to-end browser tests are the only kind of tests that change the state of the entire application each time an element on a web page is changed. I treat When steps as verbs. Just as every Then step should have an assertion, every When step should have an action, like click(), select(), enter(). A test suite that enforces a convention that every Given step is part of setup, and every When step contains an action, and every Then step contains an assertion turns out to be a powerful and surprisingly maintainable set of tests, even when the suite grows large.

Finally, I tend to write tests whose working life is long, typically years long. In a span of years, an application can change significantly with old tests still being valuable. Institutional knowledge of the behavior of the application will be gained and lost over a span of years.

I find that when one of my tests fails after a year, or two years, or three years, the cause of the failure may not be immediately apparent from the failure message or the from the code that caused it. Just as a well-written Cucumber Scenario is valuable to someone new, when a test fails after a long time, it is also valuable as a plain-English description of what the test was intended to accomplish.