In the previous chapter of Data Tables in Cucumber, we consider a very simple example of passing UserName and Password in the step. Let's take a little complex scenario where  a good amount of data is required to pass in the step. Or what is there are multiple columns of test data is present. How would you handle it? The answer is to make a Use of Maps in Data Tables.

Maps in Data Tables

Maps in Data Tables can be used if different ways. Headers can also be defined for the data tables. A same step can be executed multiple times with different set of test data using Maps.

Maps in Data Tables with Header

In the previous chapter of Data Tables in Cucumber,  we pass Username & Password without Header, due to which the test was not much readable. What if there will be many columns. The basic funda of BDD test is to make the Test in Business readable format, so that business users can understand it easily. Setting Header in Test data is not a difficult task in Cucumber. take a look at a below Scenario.

Feature File Scenario

Scenario: Successful Login with Valid Credentials
	Given User is on Home Page
	When User Navigate to LogIn Page
	And User enters Credentials to LogIn
	| Username   | Password |
    | testuser_1 | Test@153 |
	Then Message displayed Login Successfully

The implementation of the above step will be like this:

@When("^User enters Credentials to LogIn$")
	public void user_enters_testuser_and_Test(DataTable usercredentials) throws Throwable {

		//Write the code to handle Data Table
		List<Map<String,String>> data = usercredentials.asMaps(String.class,String.class);
		driver.findElement(By.id("log")).sendKeys(data.get(0).get("Username")); 
	    driver.findElement(By.id("pwd")).sendKeys(data.get(0).get("Password"));
	    driver.findElement(By.id("login")).click();
           }

Maps in Data Tables with Multiple Test Data

In this test we will pass Username and Password two times to the test step. So our test should enter Username & Password once, click on LogIn button and repeat the same steps again.

Feature File Scenario

Scenario: Successful Login with Valid Credentials
	Given User is on Home Page
	When User Navigate to LogIn Page
	And User enters Credentials to LogIn
	| Username   | Password |
    | testuser_1 | Test@153 |
    | testuser_2 | Test@154 |
	Then Message displayed Login Successfully

The implementation of the above step will be like this:

	@When("^User enters Credentials to LogIn$")
	public void user_enters_testuser_and_Test(DataTable usercredentials) throws Throwable {

		//Write the code to handle Data Table
		for (Map<String, String> data : usercredentials.asMaps(String.class, String.class)) {
			driver.findElement(By.id("log")).sendKeys(data.get("Username")); 
		    driver.findElement(By.id("pwd")).sendKeys(data.get("Password"));
		    driver.findElement(By.id("login")).click();
			}

	}

Map Data Tables to Class Objects

Luckily there are easier ways to access your data than DataTable. For instance you can create a Class-Object and have Cucumber map the data in a table to a list of these.

Feature File Scenario

Scenario: Successful Login with Valid Credentials
	Given User is on Home Page
	When User Navigate to LogIn Page
	And User enters Credentials to LogIn
	| Username   | Password |
    | testuser_1 | Test@153 |
    | testuser_2 | Test@154 |
	Then Message displayed Login Successfully

The implementation of the above step will be like this:

	@When("^User enters Credentials to LogIn$")
	public void user_enters_testuser_and_Test(List<Credentials>  usercredentials) throws Throwable {

		//Write the code to handle Data Table
		for (Credentials credentials : usercredentials) {			
			driver.findElement(By.id("log")).sendKeys(credentials.getUsername()); 
		    driver.findElement(By.id("pwd")).sendKeys(credentials.getPassword());
		    driver.findElement(By.id("login")).click();
			}		
	}

Class Credentials

package stepDefinition;

public class Credentials {
	private String username;
	private String password;

	public String getUsername() {
        return username;
    }
	public String getPassword() {
        return password;
    }	
}

Conclusion

The previous chapter passed a username and password without a header row, which worked but was not readable — and readability is the whole point of a BDD test. Maps solve that. Adding a | Username | Password | header lets asMaps() return a List<Map<String,String>>, so the step definition fetches values by name with data.get(0).get("Username") instead of by position. With many columns, that difference stops being cosmetic.

From there we covered two extensions. Adding more rows and looping over asMaps() runs the same step once per row, entering each set of credentials in turn — useful when one step needs to be repeated with different data. And rather than handling the DataTable yourself at all, you can declare a Credentials class with matching fields and accept List<Credentials> as the step parameter. Cucumber maps each row to an object, and the code reads credentials.getUsername() — no table handling, no string keys, and a compile-time check on the field names.

That last approach is the one worth carrying into a real framework, because the class documents the shape of the data in one place.

Next, we look at Cucumber Tags.

Data Tables in Cucumber
Data Tables in Cucumber
Previous Article
Cucumber Tags
Cucumber Tags
Next Article
Harish Rajora
I am a computer science engineer. I love to keep growing as the technological world grows. I feel there is no powerful tool than a computer to change the world in any way. Apart from my field of study, I like reading books a lot and developing new stuff.
Reviewers
Virender Singh's Photo
Virender Singh

Similar Articles

Feedback