Gwen Automation with Data Tables

Gwen now supports data tables and in this post I’m going to show you some examples of how they can be used with the web engine to automate some repetitive tasks on the TodoMVC web application.

Data tables are handy for when you want to work with lists of items in Gherkin, such as the list of todo items shown in this example below.

File: features/todo/tables/TodoTables.feature


 Feature: Managing todo items with data tables

Scenario: Complete a todo item

    Given I have the following active items
          | Walk the dog |
          | Get the milk |
          | Feed the cat |

     When I complete the "Get the milk" item

     Then the status of my items should be
          | Item         | Status    |
          | Walk the dog | active    |
          | Get the milk | completed |
          | Feed the cat | active    |

Note that this example is a high level (or declarative) feature specification that describes intended behaviour and not a low level (or imperative) list of statements that describe how automation is to be achieved or on what type of system it will be performed on. Those are automation bindings that can be captured in separate meta files that are also expressed in Gherkin when using Gwen. As it turns out, we already have a meta file that specifies some step definitions that call out to predefined steps in the web engine to interact with the TodoMVC app. One of the capabilities of Gwen is the ability to reuse this meta, so we will reuse it here to help compose some step definitions for our data tables above. You can have a look at that Todo.meta file here if you like.

Data Table Bindings

Looking at the first Given step in our feature, we can see that it contains three todo items in a table. The step implies that we have those three items in our todo list. So what we want to do is load those three items into our list in the todo app when running this step. To do that, we need to create a step definition for it that will launch the app, load the items, and verify that they are all active. We can do that with some new meta as follows:

File: features/todo/tables/TodoTables.meta

 Feature: TodoMVC tables meta

@StepDef
@DataTable(horizontal="Item")
Scenario: I have the following active items
    Given I launch the Todo app
     When I add a "${data[1][Item]}" item
      And I add a "${data[2][Item]}" item
      And I add a "${data[3][Item]}" item
     Then the "${data[Item]}" item should be active for each data record

This meta is also a Gherkin specification with a tagged scenario containing all the steps that will perform the desired operations on the data table.

  • This first @StepDef tag tells Gwen to load this scenario to memory and only execute its steps when a step in a feature references it by name. Note that the name of this scenario is the same expression used in the Given step in the feature. This is how step definitions work in Gwen.
  • The second @DataTable tag contains an attribute that declares the table to contain horizontal data records and that each one of those contains just one data cell that we will call “Item”. We need to do this since the table in the feature does not include a header record at the top and we have to assign each cell a name so we can access its data by that name.
  • The steps from lines 7 to 9 load the items one at a time by explicitly referencing the data in each record
  • The last step on line 10 checks that each item is active by iterating over each record of the table

With this in place and the latest web engine installed, we can now invoke the feature with Gwen as follows.

gwen -b features/todo/tables/TodoTable.feature

Gwen will automatically discover and load the automation bindings in all meta files that exist in the path of the feature file which in our case includes both the Todo.meta we want to reuse and the TodoTables.meta we just created. The Given step in the feature will execute to load the table items and verify that they are all active, and the When step will complete the second item. The Then step in the feature will fail as expected because we haven’t defined a step definition for it yet. The web browser output is shown below:

Similarly, we now add a step definition for the last Then step in our feature to our meta to verify the status of all items and complete all our binding work.

    • The table in this step includes a header record, so we specify header="top" in the @DataTable tag to link the names in that header to the cells in each data record.

    File: features/todo/tables/TodoTables.meta

     Feature: TodoMVC tables meta
    
    @StepDef
    @DataTable(horizontal="Item")
    Scenario: I have the following active items
        Given I launch the Todo app
         When I add a "${data[1][Item]}" item
          And I add a "${data[2][Item]}" item
          And I add a "${data[3][Item]}" item
         Then the "${data[Item]}" item should be active for each data record
    
    @StepDef
    @DataTable(header="top")
    Scenario: the status of my items should be
         Then the "${data[Item]}" item should be ${data[Status]} for each data record
    

    Now the entire feature is executable!

    Simplifying it Further

    For the sake of demonstrating explicit table data access, the steps from lines 7 to 9 in our meta process each record one at a time. Imagine if we had a lot more records? There would be a lot of redundancy wouldn’t there? We can remove this by reducing these steps into a single step that loops through each record in the same way that the steps on line 10 and 15 do.

    File: features/todo/tables/TodoTables.meta

     Feature: TodoMVC tables meta
    
    @StepDef
    @DataTable(horizontal="Item")
    Scenario: I have the following active items
        Given I launch the Todo app
         When I add a "${data[Item]}" item for each data record
         Then the "${data[Item]}" item should be active for each data record
    
    @StepDef
    @DataTable(header="top")
    Scenario: the status of my items should be
         Then the "${data[Item]}" item should be ${data[Status]} for each data record
    

    Now there is no need to explicitly specify the index for each record when referencing each data cell. But for cases where you might need to cross reference different records or really want to be explicit in how you access each data cell, the earlier approach of not iterating will give you the flexibility you need. It really depends on your particular use case and you should always choose the approach that works the best in the given circumstance.

    The feature and meta files created here are available in our samples features/todo/tables folder on Github and are also bundled with the Gwen-web binary distribution. If you download and install it, you can execute the feature in the same way that we did above in your installation directory.

    And, that’s it! Our feature with tables is executable and all redundancy has been removed from the bindings. We have mapped declarative feature steps to imperative steps in meta and reused some existing meta too! 🙂

Advertisements

Published by

Branko Juric

Imperative by day and functional by night. Co author of the Gwen automation platform.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s