November 8, 2021

The Cheezy Internet: Composing tests using Cucumber and Gherkin

This is fourth in a series of blog posts. Care to go back to the beginning?

Following along with Jeff "Cheezy" Morgan's eBook, "Cucumber and Cheese: A Tester's Workshop" (2017), after setting up a development environment, we started creating in Ruby + Watir the basic building blocks for an automated test framework, as we saw in the last Adventures in Automation blog entry. 

Instead of going into great detail testing against the complex test site Jeff uses in Chapter 4: Cucumbers and Puppies of is book, with Sally's Puppy Adoption Agency, we are using the simpler test site, The-Internet, by Dave Haeffner. 

This blog post will explore scaffolding a site and composing acceptance tests using Cucumber and Gherkin. 

Scaffolding a Site Using TestGen

It's always a challenge for me when creating a new project to figure out where everything should go. What should the folder and file structure be? Luckily, Jeff Morgan created a Ruby gem called "testgen" which solves all of these problems. 
  • Change the directory to the src folder in your home directory: cd ~/src
  • Pick a name for your project, such as "cheezy_internet"
  • Install Jeff Morgan's Ruby gem testgen on your local machine: gem install testgen 
  • Use the Ruby gem testgen to create a new file hierarchy: testgen project cheezy_internet 

The following files will be created:
PS C:\Users\tmaher\src> testgen project cheezy_internet  
    create cheezy_internet  
    create cheezy_internet/cucumber.yml  
    create cheezy_internet/Gemfile  
    create cheezy_internet/Rakefile  
    create cheezy_internet/features  
    create cheezy_internet/features/support  
    create cheezy_internet/features/step_definitions  
    create cheezy_internet/features/support/env.rb  
    create cheezy_internet/features/support/hooks.rb  
    create cheezy_internet/features/support/pages  
  • Go into the new project folder that was created: cd cheezy_internet
  • Install everything with: bundle install

You can then use VS Code to open the new "cheezy_internet" folder. 

Creating New Test Features in Cucumber

From / Docs / Overview: "Cucumber is a tool that supports Behaviour-Driven Development(BDD). If you’re new to Behaviour-Driven Development read our BDD introduction first.

"Cucumber reads executable specifications written in plain text and validates that the software does what those specifications say. The specifications consists of multiple examples, or scenarios. [...]

"Each scenario is a list of steps for Cucumber to work through. Cucumber verifies that the software conforms with the specification and generates a report indicating ✅ success or ❌ failure for each scenario. In order for Cucumber to understand the scenarios, they must follow some basic syntax rules, called Gherkin.

"[...] Step definitions connect Gherkin steps to programming code. A step definition carries out the action that should be performed by the step. So step definitions hard-wire the specification to the implementation".

Features Craft Step Definitions

"The purpose of the Feature keyword is to provide a high-level description of a software feature, and to group related scenarios.

"The first primary keyword in a Gherkin document must always be Feature, followed by a : and a short text that describes the feature.

"You can add free-form text underneath Feature to add more description.

"These description lines are ignored by Cucumber at runtime, but are available for reporting (they are included by reporting tools like the official HTML formatter)". - / Gherkin Reference

Let's say we want to write about the Login feature of The-Internet. We can create a new file under the "features" folder called "Login.feature".

Feature: User Logging into Secure Area

    As an authorized user
    I want to be able to log im
    So that I can access the secure area

    Scenario: Valid User
        Given I arrive on the Login screen
        When I log in using valid credentials
        Then I should arrive at the Secure Area

We can run this features, if we are on the main "cheezy_internet" folder from the command line:

  • cucumber features\Login.feature
Since we don't yet have any step_definitions yet, it gives us samples to go by. If you wanted to you could create a new Ruby file under "step_definitions", and copy and paste the Given, When and Then. 

 1 scenario (1 undefined)  
 3 steps (3 undefined)  
 You can implement step definitions for undefined steps with these snippets:  
 Given('I am on the Login screen') do  
  pending # Write code here that turns the phrase above into concrete actions  
 When('I log in using valid credentials') do  
  pending # Write code here that turns the phrase above into concrete actions  
 Then('I should arrive at the Secure Area') do  
  pending # Write code here that turns the phrase above into concrete actions  

Refine The Feature File

Let's say we wanted to explicitly feed in the username and password into the test, so that we could share the test among many different sets of valid credentials, we could rewrite the feature file: 

Feature: Logging into Secure Area

    As an authorized user
    I want to be able to log im
    So that I can access the secure area

    Scenario: Valid User Login
        Given I am on the Login screen
        When I log in using "tomsmith" and "SuperSecretPassword!"
        Then I should arrive at the Secure Area
        And I should see "Welcome to the Secure Area"

Running the test, and copying-and-pasting into a new file called "login_steps.rb" under the "step_definitions" folder, we get: 

Given('I am on the Login screen') do
    pending # Write code here
  When('I log in using {string} and {string}') do |string, string2|
    pending # Write code here
  Then('I should arrive at the Secure Area') do
    pending # Write code here
  Then('I should see {string}') do |string|
    pending # Write code here

Parts of a Step Definition File / Gherkin Reference: "Given steps are used to describe the initial context of the system - the scene of the scenario. It is typically something that happened in the past.

"When Cucumber executes a Given step, it will configure the system to be in a well-defined state, such as creating and configuring objects or adding data to a test database.

"The purpose of Given steps is to put the system in a known state before the user (or external system) starts interacting with the system (in the When steps). Avoid talking about user interaction in Given’s. If you were creating use cases, Given’s would be your preconditions [...]

"When steps are used to describe an event, or an action. This can be a person interacting with the system, or it can be an event triggered by another system.

"It’s strongly recommended you only have a single When step per Scenario. If you feel compelled to add more, it’s usually a sign that you should split the scenario up into multiple scenarios. [...]

"Then steps are used to describe an expected outcome, or result.

"The step definition of a Then step should use an assertion to compare the actual outcome (what the system actually does) to the expected outcome (what the step says the system is supposed to do).

"An outcome should be on an observable output. That is, something that comes out of the system (report, user interface, message), and not a behaviour deeply buried inside the system (like a record in a database)".

Fill Out The Step Definition

Let's say we enter the browser test code we came up with in the last blog entry, we get:

Given('I am on the Login screen') do
    @browser = :chrome
    @browser.goto ''
When('I log in using {string} and {string}') do |username, password|
  @browser.text_field(id: 'username').set(username)
  @browser.text_field(id: 'password').set(password)
  @browser.button(value: 'Login').click
Then('I should see {string}') do |text|
    fail "Expected text not found: #{text}" unless @browser.text.include? text

Hrm. The "Then" clause could be better.  Let's use the "expect" RSpec matcher:

Then('I should see {string}') do |expected|
    expect(@browser.text).to include expected

Going back to the Given and When clause, we can also replace the parentheses and single quotes with regular expressions and Capture groups.

What are Capture Groups in Cucumber?

Jeff Morgan's "Cucumbers and Cheese":

"Cucumber has something called Capture Groups. This is simply anything that is surrounded by
parentheses. Whatever matches the capture group is placed into a variable passed to the block.
Let’s look at an example. In the previous chapter we had the following step:

"When /^I enter "([^"]*)" in the address field$/ do |address|

"The capture group is ([^"]*) and the value found there is placed in the address parameter.

"We forced this to happen by placing the double quotes around the value in the feature file and
cucumber took this as a clue to create the capture group. The truth is that there is really no need for
the double quotes. If you remove them from both the feature file and step definition you will see
that it works exactly the same.

"The last capture group and regular expression ([^"]*) is somewhat complex. Let’s spend a little
time and see what we can do to simplify it. Here are a few simple things to learn to help you write
simple regular expressions for cucumber.

• "The . character will match any character. For example .. matches “at” and “on” but it doesn’t
match “off” since it is three characters.
• "The * character means zero or more of the previous element so ab* matches “ab”, “abb” and
“a”. a.* matches “a”, “ab”, “abb”, “ac”, etc.
• "The + character means one or more of the previous element so ab+ matches “ab”, “abb” but
does not match “a”. a.+ matches “ab”, “abb”, “ac” but does not match just “a”.
• "Character classes are any set of characters contained within []. For example, [0123456789]
matches any number. [0-9] is shorthand for this example. Another common character class
is [A-Za-z] to represent any alpha character.
• "There are shorthand expressions for character classes. Here are a few: \d is equal to [0-9], \w
is equal to [A-Za-z0-9_], \s is equal to [ \t\r\n\v\f]".

"[^"]*"matches something (or nothing) in double quotes

Given /^I am on the Login screen$/ do
    @browser = :chrome
    @browser.goto ''
When /^I log in using "([^"]*)" and "([^"]*)"$/ do |username, password|
  @browser.text_field(id: 'username').set(username)
  @browser.text_field(id: 'password').set(password)
  @browser.button(value: 'Login').click
Then /^I should see "([^"]*)"$/ do |expected|
    expect(@browser.text).to include expected

Create a Scenario Outline

What if there were many different valid usernames and passwords you could pick and choose from? 

From / docs / gherkin: "The Scenario Outline keyword can be used to run the same Scenario multiple times, with different combinations of values [...]. Copying and pasting scenarios to use different values quickly becomes tedious and repetitive [...] We can collapse [...] similar scenarios into a Scenario Outline.

"Scenario outlines allow us to more concisely express these scenarios through the use of a template with < >-delimited parameters"

Cucumber allows us to create a Scenario Outline, where data can be fed into the test, executing once per row of test data. 

Feature: Logging into Secure Area

    As an authorized user
    I want to be able to log in
    So that I can access the secure area

    Scenario Outline: Valid User Login
        Given I am on the Login screen
        When I log in using "<username>" and "<password>"
        Then I should see "Welcome to the Secure Area"

        | username | password             |
        | tomsmith | SuperSecretPassword! |  

Now, we have a (mostly) complete feature file, and an improved step definition file. 

With the next blog article, we will explore adding Page Objects into our little project. 

Happy Testing!

-T.J. Maher
Sr. QA Engineer, Software Engineer in Test
Meetup Organizer, Ministry of Testing - Boston

Twitter | YouTubeLinkedIn | Articles


Kaylee Brown said...

Accounting is a subject that demands much more than subject knowledge like marketing mathematics statistics of the few. So even if you are very attentive in your class, chances are you might have missed any of the lectures on the above subjects, and thus it is becoming very challenging for you to complete those accounting assignments. It is okay to look for accounting homework assignments online as they can help you fight the stress you feel due to the submission. Finding an accounting assignment help is not easy. Still, with a little due diligence, you are sure to get a finished copy that is authentically made for you by an accounting expert, this way; you will have a better chance of building the things you love to accomplish.

Aaron jhonson said...

Thank you for sharing such a useful article. It will be useful to those who are looking for knowledge. Continue to share your knowledge with others through posts like these, and keep posting on
Data Engineering Services 
Advanced Data Analytics Solutions
Data Modernization Services
AI & ML Service Provider

John David said...

It's actually an important blog entry. This blog momentarily clarifies about APP Development. This is one of the unmistakable programming dialects generally utilized. A debt of gratitude is in order for sharing this decent article. You can reffer more important things on this blog Mobile App Development Services

GOSTOPSITE33 said...

This is a correct blog for anybody who really wants to be made aware of this topic. You understand so much its practically challenging to argue along (not too I actually would want…Ha-ha). You certainly put the latest spin with a topic that's been discussed for decades. Great stuff, just wonderful!

GUIDE1903 said...

What’s Taking place i am new to this, I stumbled upon this I have discovered It positively helpful and it has aided me out loads. I am hoping to give a contribution & assist different users like its helped me. Great job!

Harshan said...

Nice blog, it is very impressive.

Bdd With Cucumber Online Course
Cucumber Training in Bangalore

Niyaz said...

Great Post!!! Thanks for it....
what does a Social Media Manager do?
How to Become a Social Media Manager?

Marofa said...

This is good post

Unknown said...

* These are the people who presumably would be open to turning to the health-Insurance exchanges to seek either better options for Insurance, or novel Insurance options. What Is Nsw Ctp Insurance

AT&T Software said...

There is many useful points in this blog. AT&T Software LLC comes with an incredible team of website and mobile application developers who can customize the perfect solutions to transform your business.

hire woocommerce developer
woocommerce development company

Anonymous said...

Incrediwear products increase circulation to reduce inflammation & swelling, relieve pain, restore mobility, and accelerate recovery. Unlike compression products, Incrediwear products do not need to compress to work. Instead, our technology incorporates semiconductor elements within our fabric that releases negative ions when stimulated by body heat.Increasing circulation helps bring more oxygen and nutrients to the target area, which optimizes the body’s natural healing process and accelerates post-operative recovery. Visit for more.

Milcom Institute said...

Study Advanced Diploma of Telecommunication Network Engineering in Australia. Check the details of these courses - Eligibility, Subjects, Syllabus etc. diploma of telecommunications engineering

สล็อตเครดิตฟรี said...

เล่นผ่านเว็บ pg slot สล็อตเครดิตฟรี ไม่ต้องฝาก ทดลองเล่นโดยไม่ต้องฝาก เล่นได้แบบไม่มีขีดจำกัดตลอด 24 ชั่วโมง รวมทั้งเบิกเงินในปริมาณ พีจี รับเครดิตง่าย ๆ ไม่ต้องฝากก็เล่นได้

jili slot said...

Jili Slot เป็นผู้ให้บริการเกมคาสิโนออนไลน์และก็สล็อตออนไลน์ มีเกมสนุกสนานๆให้เลือกเล่นมาก สามารถเข้าไปเล่น jili slot เล่นผ่านเว็บไซต์ของพวกเราได้เลย ที่เว็บไซต์ pgslot

Anonymous said...

에볼루션접속 먹튀검증 안전노리터 go

umeshtyagi said...

Sevenmentor is the best IT traning provider in india which provides wide range of IT courses. Here you will get valuable and authentic study material. Seven mentor is one of the fastest-growing network training institutions in the world and has a monopoly in the region.

The Best IT Training Provider in India

Essien said...

Thank you for taking the time to read a particularly exciting read. I am so glad I found and read. Great process for these contents. A million thanks for sharing.- ekounimed cut off mark for microbiology

Essien said...

It’s actually a nice and helpful piece of information. I am happy that you just shared this amazing and educative piece. Thanks for your effort putting on this piece of knowledge for viewers. ondo city polytechnic admission form closing date

johnstepan said...

I really value the quality writing you put into your blog because it contains important information.
abogados en bancarrota cerca de mi