Highgroove Face-off: Acceptance testing with RSpec versus Cucumber
Highgroovers take test-driven design (TDD) seriously, but it’s easy to become overwhelmed by the number of tools available for testing applications. However, if you know us even a little, you know that we have a lot of experience using different tools–and that we’ve developed some opinions about them.
Approaches to TDD
If you’re unfamiliar with either of these tools, here’s a quick overview of their approaches to TDD:
Using RSpec for acceptance testing isn’t very different from using it for unit testing, except that the functionality is greatly extended by using capybara to interact with the browser. For example, to log in a user, the capybara bit might look like this:
Cucumber also uses capybara to drive the browser, but affords the use of steps like “login a user with name ‘bob’ and password ‘sekret’” that are far easier to read than the more procedural steps used by RSpec.
The differences come down to readability
Because both RSpec and Cucumber require capybara to interact with the browser, you might wonder how different they could really be. The difference comes down to readability. Cucumber is often sold as a way of letting a (technically-inclined) client write the cuke to describe some very high-level functionality:
Behind this are step definitions that tell Cucumber what each step means:
I should note that while it’s possible for a client to write the features into cukes, doing so usually doesn’t work out well. Cucumber uses high-level language to describe interactions, but is more coupled to the implementation than a service like Pivotal Tracker. Asking a client write all of the cukes will likely result in the developer having to rewrite or tweak the cukes so that they make sense from a design perspective.
That said, the pros and cons of Cucumber already become apparent. On the one hand, Cucumber tests can be incredibly readable. By focusing on high-level functionality and using domain-specific terms, it is a quick way to answer the “What does this app do again?” question with minimal effort. On the other hand, you have to write the step definitions so Cucumber knows what to do with the English-worded steps, and there’s a second layer to your test that has to be maintained.
In contrast, RSpec favors more low-level details. For example, the same cuke above may look like this if writen for RSpec:
While the spec isn’t as inherently readable as the cuke, my example doesn’t fully show how RSpec can (and should) be used. It’s easy to add a helpers module to your
spec_helper to transform the previous spec into something more easily read:
Using a technique like this makes RSpec seem a bit more like Cucumber, so you might wonder why you would bother to take the additional steps. The Highgroovers I spoke with are willing to put in a little more effort with RSpec so that they’re able to stick with one tool throughout.
Tools don’t make bad tests, developers do
No matter which tool we prefer individually, everyone here agreed that tools aren’t what create bad tests–the person writing the test (and the application) lead to bad tests. Regardless of whether you prefer Cucumber or RSpec, it’s important to follow good design principles.
What are your favorite testing tools and what led you to pick them over the other options?