Skip main navigation

£199.99 £139.99 for one year of Unlimited learning. Offer ends on 28 February 2023 at 23:59 (UTC). T&Cs apply

Find out more

How we write readable feature tests with RSpec

Chris Zetter, a developer in the FutureLearn product team, talks about how the team writes feature tests after moving from Cucumber to RSpec in the pursuit of maintainable and readable tests.

Testing is an integral part of building and maintaining a large platform. When we build new parts of the FutureLearn platform we write automated feature tests to document how the new feature should work and to let us know when it doesn’t.

Cucumber Love-hate

Cucumber is a commonly used tool for writing feature specs, and seemed like the obvious choice to use when we started the project. It let us write high level behaviour driven tests from the user’s perspective:

We liked Cucumber because it meant the tests were very easy to create from our user stories, and once written, easy to read. However, there were a few downsides to using Cucumber. Firstly, we were already using RSpec for the rest of the project, so having Cucumber meant another test framework dependency that we had to maintain. Secondly, there was a cognitive overhead of switching between them because of the different DSLs and test runners. Finally, we particularly didn’t like Cucumber’s use of regular expressions, because they made it harder to follow what code is being executed when tests are run as compared to standard method invocation in Ruby.

Writing better RSpec features

So, how could we stop using Cucumber but keep the readable tests that we liked?

We had already started using RSpec features instead of Cucumber, and often they looked like this:

These had a tendency to be quite long, making it difficult to understand what they were testing. There is also no clear separation between the Arrange, Act, Assert parts of the test (known as ‘Given’, ‘When’ and ‘Then’ in the language of Cucumber). We tried adding comments to the steps in the code, but found that these suffered the same fate as comments often do in application code: after time they get out of sync with the actual code.

Typically, a method this long elsewhere in our application code would have been a red flag, which we’d normally refactor through the therapeutic act of method extraction. So why not do just that? Let’s extract those lines and name each method in the same style as a Cucumber step:

What we found

We’ve since removed all of our Cucumber features and converted most of them to these new style RSpec feature specs. They retain the benefit of readability that Cucumber previously provided, yet are much easier to write and maintain.

We made a conscious decision not to optimise for code-reuse of our extracted methods between different feature files as we were worried that it would make the tests harder to follow. We have found that some code reuse tends to happen naturally when writing multiple scenarios around a single feature.

FutureLearn - Learning For Life

Our purpose is to transform access to education.

We offer a diverse selection of courses from leading universities and cultural institutions from around the world. These are delivered one step at a time, and are accessible on mobile, tablet and desktop, so you can fit learning around your life.

We believe learning should be an enjoyable, social experience, so our courses offer the opportunity to discuss what you’re learning with others as you go, helping you make fresh discoveries and form new ideas.
You can unlock new opportunities with unlimited access to hundreds of online short courses for a year by subscribing to our Unlimited package. Build your knowledge with top universities and organisations.

Learn more about how FutureLearn is transforming access to education

Related stories on FutureLearn