Codementor Events

BDD Web Automation 05: Create Data Driven Automation Script with Doc String & Data Table

Published Sep 09, 2018Last updated Sep 18, 2018
BDD Web Automation 05: Create Data Driven Automation Script with Doc String & Data Table

Content

  • Doc String
  • Data Tables

This is the 5th post in a series, BDD Automation Test for Web UI. It mainly talks about how to write Web automation test script with Cucumber.js, a BDD test framework. You will be using Node.js as the programming language. The first post contains links to the rest posts.

We explained that in a feature file a scenario can describe test case with a list of steps, each step has one sentence. Within the step text, you can use numbers or quoted text as parameters, which can be passed to step definition function in runtime. Sometimes the parameters embedded in the step text is not sufficient. We may need a block of long text, or a table of data as parameter. In this article, we will introduce Doc String and Data Table in step.

Doc String

When writing a step, if some information you provide cannot be placed on one line, you can put them in Doc String, which is a multi-line text block. In Gherkin format, Doc String is a block of text start with three parallel double quotes """. Note that the character is double quote in English, not the full-width double quotes appear in pair (e.g. “”) in Asian languages. Suppose we have a scenario about how to post a new question on StackOverflow site, the content of the post body can be placed in a Doc String:

5.png

Below is the text of this scenario:

 Scenario: Ask a new question on StackOverflow
    Given click [Ask Question] button
    When input question Title as "How to use Cucumber DocString"
    And input question Body as
      """
      I am kind of newbie to Cucumber, when I learn Cucumber, 
      I don't know how to use it in the code, 
      can anyone give an example?
      """
    And I click [Post Your Question] button
    Then the question should be posted

In the JavaScript code, the Doc String is automatically passed to the function as a string variable, like the following:

When(/^input question Body as$/, async function (docString) {
    console.log(docString);
});

Test this scenario in CukeTest by just clicking the “Run” arrow button on the scenario title, you can see the output as the following:

6.png

In real implementation, you should use WebDriver to actually insert the doc string into the Body element on web page, and we will talk about that in later articles.

Not only can plain text be put in doc string, if you need an object of data, you can also put JSON string inside doc string, and in the code, just use JSON.parse statement to parse the string to an object and then use it.

Data Tables

Sometimes a step requires an array of data, in which case you can use Data Table.

Here is a scenario of sending emails, which use data table in the first step and doc string in the second step.

7.png

The corresponding text version:

  Scenario: Send emails
    Given the following people exist:
      | name  | email           |
      | Jason | jason@email.com |
      | Joe   | joe@email.com   |
      | Zark  | zark@email.org  |
    Then send email with title "Thank you for your contributions" to each of them
      """
      Dear <name>,
      
      Thank you a lot for your contributions to Cucumber community, 
      blah blah blah...
      """

In CukeTest, you can just right click a step and click “Add Table” button from step toolbar to add this table. Then you can perform a serial of operations on the table.

In code, Cucumber provides 4 parsing methods for Table data:

  1. with column headers
  • hashes: returns an array of objects where each row is converted to an object (column header is the key)
  • rows: returns the table as a 2-D array, without the first row
  1. without column headers
  • raw: returns the table as a 2-D array
  • rowsHash: returns an object where each row corresponds to an entry (first column is the key, second column is the value). rowsHash can only be called on a data table where all rows have exactly two columns.

To better understand these four methods, we can print the data for comparison.
We use the following JavaScript implementation for this scenario.

const { Given, When, Then } = require('cucumber')

Given(/^the following people exist:$/, async function (table) {
    this.addresses = table.hashes(); //store the address from the world
    //print out 4 different format to see differences
    console.log('rows', table.rows());
    console.log('hashes', table.hashes());
    console.log('raw', table.raw());
    console.log('rowsHash', table.rowsHash());
});

Then(/^send email with title "([^"]*)" to each of them$/, async function (title, docString) {
    this.addresses.map(({name, email}) => {
        mail = {
            TITLE: title,
            TO: name,
            BODY: docString.replace("<name>", name)
        };
        //simulate sending mail
        console.log(mail);
    })
});

You can run this scenario in CukeTest, below is partial printec output that shows these 4 different table formats:

hashes [ { name: 'Jason', email: 'jason@email.com' },
  { name: 'Joe', email: 'joe@email.com' },
  { name: 'Zark', email: 'zark@email.org' } ]
rows [ [ 'Jason', 'jason@email.com' ],
  [ 'Joe', 'joe@email.com' ],
  [ 'Zark', 'zark@email.org' ] ]
raw [ [ 'name', 'email' ],
  [ 'Jason', 'jason@email.com' ],
  [ 'Joe', 'joe@email.com' ],
  [ 'Zark', 'zark@email.org' ] ]
rowsHash { name: 'email',
  Jason: 'jason@email.com',
  Joe: 'joe@email.com',
  Zark: 'zark@email.org' }

Among them, hashes() is more common to use for table with headers, and raw() is more commonly used for table without headers.

In this implementation, the first step definition assign the table data to World object. World is a concept in Cucumber, which is an object stores Scenario related data, usually to store variables that used among steps within the same scenario. In BDD and Cucumber, each step can only have either Data Table or Doc String, not both. If you want to use both of them in your scenario, you should put them in two different steps. And in the code, cache the data in the World object until all the data are available and then do the operation. In the above example, we store the table data in the World, and use it in the second step definition to send out mail.

The introduction of table allows test scripts to better support data drivers. In CukeTest, editing table is very convenient. For example, you can import data tables via csv, or export it to CSV, like Example table we introduced earlier.

You can double click it to edit the table, or right click to get the table context menu, which can perform further operations on the table.

8.png

Summary

In this post, we talked about two special parameters in Gherkin file format, Doc String and Data Table. In the next post we will talk about how to generate and update step definition functions within CukeTest.

Previous Post: 05. Create Data Driven Automation Script with Doc String & Data Table
Next Post: 07. Use Chrome Browser for Automation
First Post: 01. Create and Run the First Sample

Discover and read more posts from CukeTest
get started