Cucumber Cheat Sheet (2018 update)

A Cucumber is a software tool based on Behavior Driven Development (BDD) framework which is used to write acceptance tests for the web application. The tests are written in easily readable and understandable format for Business Analysts, Developers and Testers.

It is like reading plain English texts!

Syntax

Cucumber tests are divided into individual Features. These Features are subdivided into Scenarios, which are sequences of Steps:

  • Given - Describes the initial state before the start of a test.
  • When - Describes user actions during a test.
  • Then - Describes results from When actions.

Occasionally, you might want to write a combination of Given-When-Then. You can use the following conjunctions keywords:

  • And - Logical AND
  • But - Negative form of AND

Before we start, you might want to consider using VCR and Webmock for Cucumber testing. Once we are ready, let's try implementing the tests!

Action steps

First, we will start with the most common actions users do every day when using a web application.

Sign in

Sign in is an action everyone does multiple times per day. To sign in a user in our application we will create a new user and use login_as function provided by warden test helpers (assuming we are using devise for authentication).

# And I am signed in
And(/^I am signed in$/) do
  @user = create(:user, email: 'user@example.com', password: 'password')
  login_as(@user, scope: :user)
end

Clicking on an element

Every so often we click on an element in our browser. All this clicking has to be covered with tests, you can describe them in many different ways. Here are some examples:

# When I click on element ".element"
When(/^I click on element "(.*?)"$/) do |selector|
  find(selector).click
end

# And I click on text "Sign in"
And(/^I click on text "(.*?)"$/) do |text|
  click_text(text)
end

def click_text(text)
  elem = find(:xpath, "//*[contains(translate(text(), '#{text.upcase}', '#{text.downcase}'), '#{text.downcase}')]", match: :first, wait: false)
  scroll_to(elem, -200)
  elem.click
end

Capybara has a great toolkit for testing interaction with elements in your web application, as well!

Existence of a specific text

Once we have clicked on an element and selected the "Sign in" text with the help of click_text(text) helper method and then a text content will appear:

# Then I should see "First Name"
Then(/^I should see "(.*?)"$/) do |content|
  expect(page).to have_content(/#{Regexp.quote(content)}/i)
end

Now, you have discovered the existence of a specific text on the page, in this case, "Fist Name".

Forms steps

Filling up forms is another common action. Let's start with filling input, selecting the dropdown option and clicking on the checkbox examples.

Filling input

The input filed can only accept element selectors and values as the input. First, we will select an input field and then fill it with a specified value.

# When I fill in "test" for field "user[user_attributes][first_name]"
When(/^I fill in "(.*?)" for input element "(.*?)"$/) do |value, selector|
  all(selector).last.set(value)
end

Selecting dropdown option

You can only use element selector and option value as selected dropdown options. The option will be selected depending on the value.

# When I select option "My Test Inc Account" from ".accounts-dropdown"
When(/^I select option "(.*?)" from element "(.*?)"$/) do |option, selector|
  all(selector).last.find(:option, option).select_option
end

Clicking checkbox

In the following example, you can only select a checkbox name which is used for finding and checking the element.

# When I select checkbox "report_type_summary"
When(/^I select checkbox "(.*?)"$/) do |cb|
  check(cb)
end

There are many different ways to write tests, especially in Ruby on Rails. Another very popular testing framework is RSpec, be sure to take a look.

One way to build your testing data for RSpec is with FactoyBot.

You can navigate through a page by the page name and value, different values can mean different pages. It will raise Missing mapping for '#{page_name}' page. exception if the page name is not defined.

# Given I am on page users board
Given /^I am on page ?(.+)?$/ do |page_name|
  case page_name
  when 'homepage'
    visit root_path
  when 'users board'
    visit users_path
  when 'products board'
    visit product_path
  else
    raise "Missing mapping for '#{page_name}' page."
  end
end

Why don't we put our new knowledge into practice and start writing tests for a modal?

Waiting for ajax

Clicking on a button will trigger an ajax call and you will need to simulate the delay before your application responds to it. You can define the helper method that calls the sleep function:

def wait_for_ajax
  sleep 2
end

Always keep this cheat sheet close to you, to be there when you need it!

Don't forget to test our subscribe input fields!