An Introduction to Testing With Cucumber

Cucumber is a software tool for implementing behavior driven development (BDD). Through it's use of the plain language parser Gherkin, Cucumber features human readable test definitions and scenarios that are easily understandable by stakeholders and developers alike. In this article, we explore the basics of Cucumber including how it works and key components of the Cucumber test framework.

What is Cucumber?

Cucumber is a tool for writing automation tests based on BDD principles. It's written in Ruby but supports an array of different programming languages including PhP and Java. To understand the value Cucumber provides to your test suite, it's important to first understand the concept of BDD:

What is BDD?

BDD is largely based on the concepts of test driven development (TDD) where requirements are expressed as test cases that "drive" development of the software. The main idea is that the tests dictate how the application is developed rather than tests being written retroactively for code that’s already been written.

BDD takes TDD a step further by expressing tests as human readable specifications. Tools like Cucumber allow business analysts/stakeholders to write plain text specifications (using Gherkin syntax) that correspond to test scenarios written by developers. Using Cucumber, tests can be written using plan expressions like "given", "when", "then", etc. This allows stakeholders to write acceptance tests that describe behavior from the customer perspective.

How Cucumber Works

Cucumber uses the Gherkin syntax to describe different features in feature files. Each feature file describes an individual feature with a given number of scenarios. Each scenario has a given number of steps that correspond to a separate step file. Within the step file, the actual code blocks are written for executing the different steps for a given scenario. The general format for a feature file is as follows:

Feature: <description>

An example of a feature file:

Feature: HTTP Response test

  As a end-user
  I want to get a JSON response
  So I know the endpoint is working

  Scenario: make HTTP request
    Given I haven't made the request
    When I make a request
    Then the response is a JSON object

In this example, we first define our feature with a description "HTTP Response test". We then define an optional story definition describing the user, what they are doing, and why they care. We then define a scenario for making an HTTP request. Notice the use of Given, When, and Then. These are the different steps that we write corresponding logic for in a separate step file.

While the implementation of your step file will vary depending on the language you're using, the general idea is the same. The step file typically uses regex to map steps defined in the feature file to executable code blocks. Following our feature file example above, a step file may include the following:

Given /^I haven't made the request$/ do |request|
  #code or logic to run for this step

Notice how we use regex to match the code block with the step description from the feature file.

Using Scenario Outlines

You can use scenario outlines to create templates for your feature files. This is useful when you have multiple values that you want to run through the same logic. For example:

Scenario Outline: HTTP response test
  Given I haven't made the <requestName> request
  When I make the  <requestType> request
  Then the response returns <response>

    | requestName    | requestType | response       |
    |  login         |  HTTP       | {secure:false} |
    |  login         |  HTTPS      | {secure:true}  |


Cucumber is a testing tool for BDD. While feature files contain the high level description of test scenarios, corresponding step files implement logic for each step in a given scenario. By using plain text and Gherkin syntax, Cucumber bridges the gap between stakeholders who define requirements and developers who build them.

Your thoughts?