kloia Blog

Slice 1: Gherkin Keywords and Cucumber Expression

Written by Muhammet Topcu | Jan 12, 2023 1:50:37 PM

Cucumber is a framework that uses Gherkin Syntax to drive Behavior Driven Development in your test infrastructure. (Need a quick primer on BDD? Check out this blogpost) In this blog post, I am going to take a glance Gherkin keywords and demonstrate the power of Cucumber Expression — the alternative to regex step definitions. 

Gherkin Keywords

Gherkin keywords have specific functionalities, such as defining features. Every feature consists of scenarios having a certain scope, and every scenario consists of steps defined by regex or Cucumber Expression in step definitions.

Feature/Ability/Business Need

  • Name of the .feature file.

  • There can be only one feature keyword per .feature file.

  • It can get description words below itself.


Feature: User Features

  Application should be tested against possible behaviors of registered users.

  Scenario: Logging in with registered user

Note: The description line shown above can also be used with Background, Rule, Scenario, or Scenario Outline (and with their aliases) unless a keyword is used beforehand.

Also note that some keywords such as Feature get semicolons as a suffix and do not work without it.

Rule

  • A keyword level between feature and scenario.

  • It can be used to group certain scenarios having the same rule.

  • Each rule can have its own background block. 

Note: Rule keyword is pretty new, and certain test case management tool integrations may support it. Also, Cucumber Extensions on some IDEs do not group scenarios by Rule keyword, so they can not be executed separately.


Background:
  Given go to home page


Rule: User must be logged in
  Background:
    Given sign in with 'username' and 'password'

  Scenario: Logging out
    When click logout button on home page
    Then verify user is logged out on home page

Rule: User must be non-logged in 
  Scenario: Verify non-logged in on refreshed page
    When go to home page
    Then verify user is not logged in

Scenario/Example

- Name of the Test Case.

- It contains Given, When, Then, And, and But keywords.

Given

- First scenario step.

- It is usually used to describe the initial context.

When

- It is used to declare events or actions specific to the aforementioned scenario.

Then

- This keyword is used to declare an expected result or outcome after the when step.

And and But

- The purpose of these two keywords is to replace Given, When, or Then keywords when they are used more than once to increase readability.

Scenario: Signing in
  Given home page is open
  When click on sign in button
  And fill areas with 'username' and 'password'
  Then 'username' is displayed on top right corner
  But sign in button shouldn't be displayed

* (Asterix)

- All Cucumber steps can be written with * keyword.

- It is best suited for listing similar steps.


Scenario: Making halva
  Given I am hungry
  * I have oil
  * I have flour
  * I have sugar
  When I make halva and eat it
  Then I am not hungry

Scenario Outline/Scenario Template

- Name of the Test Case.

- This keyword is used to run a scenario with different values consecutively. Thus, enables us to do data-driven testing

- It contains Given, When, Then, And, and But keywords.

Note: The placeholders are written inside of <> characters.

 

Examples/Scenarios

- This keyword is used along with Scenario Outline to specify the values to be replaced with placeholders.


Scenario Outline: Shop cart item removal
  Given there are  items in the cart
  When I remove  items from the cart
  Then verify  items left in the cart

  Examples:
    | start | remove | left |
    |    12 |   5    |    7 |
    |    20 |   5    |   15 |

Background

- Background is used for the general steps that should be executed for every scenario.

- It can be used with the Rule keyword, affecting only the scenarios nested inside that specific Rule.  


Background:
  Given go to home page
  And sign in with 'username' and 'password'

Scenario: Logging out
  When click logout button on home page
  Then verify user is logged out on home page

Scenario: Verify login on refreshed page
  When go to home page
  Then verify user is logged in

Cucumber Expressions

To understand Cucumber Expressions, we need to understand what a step definition is.

Scenario steps are high-level statements, and they actually don’t have any meaning as far as a programming language is concerned. To give them a purpose, we need to define what they do in the background. That is called the “step definition.

IDEs like RubyMine usually create step definitions with regex.

Cucumber Expression provides us with a different way to create a step definition. Let’s compare them with each other.


#RegEx step definition
And(/^create a user named "([^"]*)"$/) do |arg|
 pending
end


#Cucumber Expression step definition
And("create a user named {string}") do |arg|
 pending
end

As you can see from the example above, Cucumber Expression does not directly use a regex inside the step definition. It handles it differently.

Parameter Types

The text between curly braces in the example above is called parameters. There are some built-in parameters that Cucumber provides us. These are:

Built-in parameter

Description

{int}

Matches an integer. E.g. 18 or -59.

{float}

Matches a float. E.g. 9.2 or -8.3.

{word}

Matches a word without spaces. E.g. kloia.

{string}

Matches a string with a double or single quote. E.g. “kloia company”

{}

Matches anything (/.*/).

{bigdecimal}

Matches the same as {float}, converts it to BigDecimal if supported.

{double}

Matches the same as {float}, converts it to 64 bit float if supported.

{biginteger}

Matches the same as {int}, converts it to BigInteger if supported.

{byte}

Matches the same as {int}, converts it to 8-bit signed integer if supported.

{short}

Matches the same as {int}, converts it to 16-bit signed integer if supported.

{long}

Matches the same as {int}, converts it to 64-bit signed integer if supported.

If the parameters above do not meet your needs and you want to create a custom parameter using your own regex, that is also possible.

There are four main fields to create a custom parameter.

Argument

Description

name

This is the name of your parameter. This is what is used between curly brackets. For the example above, it is {name}.

regexp

Regular Expression to capture the contents of the argument.

type

The return type of the transformer.

transformer

Needs to have at least arity 1 if regex does not have any capture groups. Otherwise, argument number must be equal to the regex’s capture group count.


Note: Transformer should be a function.

Let’s say that we want to give a person’s name in the step and create a Person object with it. Here is the ParameterType configuration and step definition:


ParameterType(
 name: 'name',
 regexp: /"([^"]*)"/,
 type: Person,
 transformer: -> (arg) {Person.new(name: arg)}
)

And("create a user named {name}") do |person|
 puts person
 puts "id: " + person.id
 puts "name: " + person.name
 puts "age: " + person.age
end

The person class used inside the transformer:


class Person attr_accessor :id, :name, :age def initialize(options = {}) self.id = options[:id] || "unknown" self.name = options[:name] || "unknown" self.age = options[:age] || "unknown" end end
 

The feature file:


Feature: Step definition examples

 Scenario: creating step definitions
   And create a user named "kloia"
 

Output of the code:



# id: unknown name: kloia age: unknown

You might realize the example given above might not be the best way to handle objects, but it is a good example to demonstrate the power of Cucumber Expressions.

You may want to refer Cucumber Expression page on Git Hub.

As a finishing line, let me share an idiom I love

“To run with salt to anyone who says I have a cucumber.” - Turkish Idiom

Meaning: Trying to help everyone without thinking afterward and ending up in a bad situation.

But hey, we are going to run test cases with cucumber. There is a difference!😀