Read more

Test Driven Development with Cucumber and RSpec

Dominik Schöler
April 23, 2020Software engineer at makandra GmbH

Test Driven Development is the paradigm to "first write a test, then implement the code". This guide shows how to apply it in practice, with Cucumber and RSpec as integration and unit test frameworks.

Hierarchical approach

Illustration book lover

Growing Rails Applications in Practice

Check out our e-book. Learn to structure large Ruby on Rails codebases with the tools you already know and love.

  • Introduce design conventions for controllers and user-facing models
  • Create a system for growth
  • Build applications to last
Read more Show archive.org snapshot

I like to view TDD as a process with three levels:

  • Cucumber level (integration test)
  • Code level
  • RSpec level (unit test)

During development you are frequently changing levels. It may look something like this:

Integration _                    ___
Code         \____    _____   __/   \__ ...
Spec              \__/     \_/

Feature level

Start writing a Cucumber feature. List all usage scenarios you can think of:

Feature: <Concise description of the feature>

  <If it is a complex/questionable/very specific feature, add a motivation description or give a good overview.>

  Scenario: <Basic usage example, "happy path">

  # Add a scenario for each use case. Examples are: error behavior, access rights, contexts, closer looks at parts of the feature
  Scenario: ...

If required, add more feature files in the same manner. From these, the reader should understand everything to know about the new feature you're building.

When you're done sketching the feature, start writing out the scenarios one by one. Remember to document motivations or relevant context to a scenario if needed.

Once you are becoming unsure how a scenario will continue, it is time to turn to the code.

Code level

When starting to code, run the current Cucumber scenario. Write the code that turns the scenario green.

As soon as you're about to write code that is not covered by integration tests, drop to the specs.

Examples include:

  • a new service class
  • a method with multiple code paths (if..else, case..when etc)

Spec level

Unit tests make sure some isolated code works as expected. For each method you're testing, start by listing all usage examples you can think of:

describe <class> do
  
  describe '<method>' do
    it '<basic usage example>'
    it '<other usage example>'
    it '...'
  end

end

From these, the reader should understand everything to know about that method.

When you're done listing examples, start writing them out. Write an example, then write the code to make it green. Iterate until all Specs are complete and green.

When you're done, return to writing the code. The specced thing now exists, so you can continue making that Cucumber Scenario green.

Posted by Dominik Schöler to makandra dev (2020-04-23 16:43)