arrow_back

Getting the most out of Cucumber, Gherkin and Selenium

 

Cucumber, Selenium and Gherkin have become popular tools for helping teams implement test automation or what is often referred to as Acceptance Test Driver Development (ATDD) or Behavior Driven Development (BDD).  In this article we will cover some more advanced features of the Gherkin language that can help you write tests that are simpler and more reusable.

We will cover:

  1. Using Regular Expressions for Dynamic DataSelenium, Cucumber, Gherkin
  2. Scenario Outlines
  3. Tables as Arguments
  4. Backgrounds

In this article series we use Ruby as the implementation language (and we recommend Ruby when there is no other existing preference). However, these examples will translate easily to other languages like Java.

 

If you are not familiar with Selenium, Cucumber and Gherkin take a look at our related introductory blog "The 5 Step Guide for Selenium, Cucumber, and Gherkin".

1. Using Regular Expression for Dynamic Data

In our earlier blog, we showed you how to create Step Definitions in Ruby that translate plain text Gherkin steps into actions that will interact with the system.  For example:

Given We navigate to the homepage

 Would need a Step Definition inf Ruby that looks like this:

Given(/^We navigate to the homepage$/) do
  $driver.navigate.to "http://mock.agiletrailblazers.com"
end

In this simple example things work well, but what if you want to use a Given/When/Then statement but include dynamic data so you can reuse this statement in other tests?  Let's take another example:

When We search for the word agile

And the Step Definition:

When(/^We search for the word agile$/) do
  driver.find_element(:id, 's').send_keys("agile")
  driver.find_element(:id, 's').send_keys("\n")
end

If we want to create tests for different search values, we need to parameterize the value of the word "agile" so we can run tests for different terms.  To do this we can use regular expressions to make this more dynamic. To do this we need to change our Ruby Step Definition:

When(/^We search for the word (.*)$/) do |keyword|
  $driver.find_element(:id, 's').send_keys(keyword)
  $driver.find_element(:id, 's').send_keys("\n")
end

We have replaced the hard coded value of "agile" with the regular expression of (.*) and added a parameter to the Ruby When function of |keyword|.  This will set the variable keyword to any value that matches the regular expression.  You can create more complex regular expressions and map those to multiple variables:

When(/^the user enters a date of (\d+)\/(\d+)\/(\d+)$/) \
do |month,day,year|

If you are not familiar with Regular Expressions (knows as RegEx), they are a special text string for describing a search pattern.  Take a look at the site RegExr to learn more regular expressions. I have also found that Rubulr is a nice site for testing your regular expressions in Ruby.

2. Backgrounds

As you write more tests you will begin to find that you end up repeating the same steps over and over again.  In Gherkin a "background" is a simple way to reduce the wordiness of Gherkin.  Lets take this simple example:

Feature: Site Search
Scenario:
  Given We navigate to the homepage
  When We search for the word agile
  Then The result title Search Results for: agile will be displayed
  And There are 12 results found
Scenario: Given We navigate to the homepage When We search for the word scrum Then The result title Search Results for: scrum will be displayed And There are 21 results found Scenario: Given We navigate to the homepage When We search for the word kanban Then The result title Search Results for: kanban will be displayed And There are 6 results found

If we create more scenarios we can see how this will quickly become unwieldy.  As a result we can use the syntax "Background" to list steps that should be executed for every Scenario in a given Feature.  

Feature: Site Search

Background:
  Given We navigate to the homepage

Scenario:
  When We search for the word agile
  Then The result title Search Results for: agile will be displayed
  And There are 12 results found

Scenario:
  When We search for the word scrum
  Then The result title Search Results for: scrum will be displayed
  And There are 21 results found

Scenario:
  When We search for the word kanban
  Then The result title Search Results for: kanban will be displayed
  And There are 6 results found

Notice how in the above example we were able to reduce the number of lines and simplify the Gherkin.  But while using Background is better, there is still a great deal of repetition and this is where Scenario Outlines are helpful.

3. Scenario Outlines

Scenario Outlines allow you to design your Gherkin in such a way that you repeat the steps in the scenario once for each row in a set of inputs.  In your Given, When or Then statements you can substitute the hard coded values for a variable placeholder like <keyword>.  Then you add the "Examples" keyword and use the pipe/table format to specify the input data.  The test will be run once for each row created in the table.

Feature: Site Search

Scenario Outline:
  Given We navigate to the homepage
  When We search for the word <keyword>
  Then The result title <title> will be displayed
  And There are <count> results found

Examples:
  | keyword | title | count |
  | agile | Search Results for: agile | 12 |
  | scrum | Search Results for: scrum | 21 |
  | kanban | Search Results for: kanban | 6 |

While Scenario Outlines are very useful I would caution against trying to use Automated Functional Tests as a way to test business logic.  Business logic is best tested using Unit Tests or Integration Tests (i.e. API tests, etc).  For Functional (or UI) tests the recommendation is to focus on testing the behavior of the UI and not on the business logic.

4. Tables as Arguments

In some cases you will find you need a test to verify some list or set of data on a page.  Rather than hard code this into your Step Definition you can use the Gherkin "Tables as Arguments" feature to pass a table of data to a Step Definition.  Let's take this example - you have a web page which displays a list of cities (Philadelphia, New York, Cleveland, Orlando, etc).  You could write your Gherkin this way:

Scenario: Validate the list of cities webpage
  Given the user is on the cities webpage
  Then confirm we see the the city Philadelphia
  And confirm we see the the city New York
  And confirm we see the the city Orlando
  And confirm we see the the city Cleveland
  And confirm we see the the city Pheonix
  And confirm we see the the city Seattle
  And confirm we see the the city Boston

Since this is quite repetitive we can use Tables as Arguments instead.  The Gherkin would be:

Scenario: Validate the list of cities webpage
  Given the user is on the cities webpage
  Then confirm we see the following cities
    | city         |
    | Philadelphia |
    | New York     |
    | Orlando      |
    | Cleveland    |
    | Pheonix      |
    | Seattle      |
    | Boston       |

 And the Step Definition in Ruby would look like:

Then(/^confirm we see the following cities$/) do |table|
  $wait = Selenium::WebDriver::Wait.new(:timeout => 5) # seconds
  data = table.hashes
  data.each do |row|
    row.each do |key, value|
      #locate each value from the table on the page
      element = $wait.until { \
        $driver.find_element(:xpath, './/*[contains(., "' + value + '")]') }
    end
  end
end

The table gets passed into the Step Definition as a hash of key/value pairs and we can loop through and verify each element which was passed in can be found on the page.


In our examples above, we created only automated functional tests but it's important to remember this is only one part of a good automation strategy, which will also include integration and unit tests.  For more on this, see our related blog about organizational testing strategy

To become an ICAgile Certified Professional in Agile Testing or to learn more about automation and Agile testing check out our courses.

Learn More

 

 


Learn more about modernized technology here:

Develop solutions with speed/quality


 


Interested in training to help advance your agile journey? Click the button to view our current list of public training courses! Use code BLOG10 for 10% off!

View Public Training Course Listing