How to Create a BDD Automation Framework using Cucumber in Java and Playwright?
Behavior Driven Development (BDD) is a process that promotes collaboration between developers, testers, and stakeholders by writing test cases in simple, plain language. BDD Automation Frameworks like Cucumber use Gherkin to make test scenarios easily understandable and link them to automated tests.
In this guide, we’ll show you how to create a BDD Automation Framework using Java and Playwright. Playwright is a powerful browser automation tool, and when combined with Java and Cucumber, it creates a solid BDD testing framework.
Introduction to BDD Automation Framework:
Automation testing is testing software with the latest tools and technologies with developed scripts in less time. In Automation testing it involves test case execution, data validation, and result reporting.
Why Playwright over Selenium?
Playwright is an open-source Node.js library that further enables efficient end-to-end (E2E) testing of web applications. As Playwright offers better performance speed than Selenium. Also, Playwright offers various features like Cross-Brower support, Multi-platform, Headless and Headful Mode, Async/Await API, Integration with Testing Frameworks.
What is BDD Automation Framework?
BDD framework is an agile approach to test software where testers write test cases in simple language so that non-tech person can also understand the flow. Moreover, it enhances collaboration between the technical team and the business team. We use Gherkin language to write feature files, making them easily readable by everyone.
Prerequisites for BDD Automation Framework:
1. Install JDK
Install the Java environment as per the system compatible.
https://download.oracle.com/java/22/latest/jdk-22_windows-x64_bin.zip
Steps:
- Download JDK:
- Go to the Oracle JDK download page.
- First, choose the appropriate JDK version, and then click on the download link for the Windows version.
- Run the Installer:
- Once the download is complete, run the installer.
- To begin, follow the installation instructions, then accept the license agreement, and finally choose the installation directory.
- Set Environment Variables:
- Open the Control Panel and go to System and Security > System > Advanced system settings.
- Click on “Environment Variables”.
- Under “System Variables,” click on “New” and add a variable named JAVA_HOME with the path to the JDK installation directory (e.g., C:\Program Files\Java\jdk-15).
- Find the “Path” variable in the “System Variables” section, click on “Edit,” and add a new entry with the path to the bin directory inside the JDK installation directory (e.g., C:\Program Files\Java\jdk-15\bin).
- Verify Installation:
- Open a Command Prompt and check if Java is installed correctly by typing `java -version` and `javac -version`.
2. IntelliJ Idea IDE for programming
https://www.jetbrains.com/idea/download/#section=windows
Steps:
- Download IntelliJ IDEA:
- Go to the JetBrains IntelliJ IDEA download page.
- Choose either the Ultimate (paid) or Community (free) edition and click the download link for Windows.
- Run the Installer:
- Once the download is complete, run the installer.
- Follow the installation instructions:
- Choose the installation directory.
- Select the components you want to install (e.g., 64-bit launcher, .java file association).
- Optionally create a desktop shortcut.
- Start IntelliJ IDEA:
- After the installation is complete, start IntelliJ IDEA from the Start menu or desktop shortcut.
- Follow the initial setup wizard to customize your IDE (e.g., theme, plugins).
3. Maven
https://maven.apache.org/download.cgi
Steps:
- Download Maven:
- Go to the Apache Maven download page.
- Click on the link to download the binary zip archive (e.g., apache-maven-3.x.y-bin.zip).
- Extract the Archive:
- Extract the downloaded zip file to a suitable directory (e.g., C:\Program Files\Apache\maven).
- Set Environment Variables:
- Open the Control Panel and go to System and Security > System > Advanced system settings.
- Click on “Environment Variables”.
- Under “System Variables”, click on “New” and add a variable named MAVEN_HOME with the path to the Maven installation directory (e.g., C:\Program Files\Apache\maven\apache-maven-3.x.y).
- Find the “Path” variable in the “System Variables” section, click on “Edit”, and add a new entry with the path to the bin directory inside the Maven installation directory (e.g., C:\Program Files\Apache\maven\apache-maven-3.x.y\bin).
- Verify Installation:
- To check if Maven is installed correctly, open a Command Prompt and type `mvn -version`.
4. Cucumber
https://mvnrepository.com/artifact/io.cucumber/cucumber-java/7.11.0
Prerequisites
- Java Development Kit (JDK): Ensure you have JDK installed and properly configured.
- Maven or Gradle: Depending on your preference, however, you’ll need Maven or Gradle to manage your project dependencies.
Steps to Install Cucumber with Maven
- Create a Maven Project:
- Update pom.xml File:
- Open the pom.xml file in your project.
This Maven POM file (pom.xml) defines project metadata, dependencies on external libraries (Cucumber, Selenium, Playwright), and Maven build properties. It provides the necessary configuration for managing dependencies, compiling Java source code, and integrating with Cucumber, TestNG, Selenium, and Playwright frameworks to support automated testing and development of the CalculatorBDD project.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>CalculatorBDD</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-java -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.12.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-testng -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>7.12.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.microsoft.playwright/playwright -->
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>1.23.0</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
Project Setup or BDD Automation Framework:
Before starting the project on the BDD Automation Framework:
- Create a new Maven project in your IDE.
- Add the dependencies in Pom.xml file .
- Create folder structure following steps given below:
When we created the new project for the executable jar file, we could see the simple folder structure provided by Maven.
- SRC Folder: The SRC folder is the parent folder of a project, and it will also include the main and test foldersIn the QA environment, we generally use the test folder, while we reserve the main folder for the development environment. The development team uses the main folder, so the created JAR contains all the files inside the src folder.
- Test Folder: Inside the test folder; additionally, Java and resources folders are available.
- Java Folder: This folder primarily contains the Java classes where the actual code is present.
- Resources Folder: The Resources folder contains the resources file, test data file, and document files.
- Pom.xml: In this file, we are managing the dependencies and plugins that are required for automation.
As our project structure is ready so we can start with the BDD framework:
1. Feature file:
Here we have described the scenario in “Gherkin” language which is designed to be easily understandable by non-technical stakeholders as well as executable by automation tools like Cucumber. Each scenario is written in structured manner using keywords “Given”, “When” and “Then”. Calculator.feature in this we have specifically written our functional testing steps.
@Basic
Feature: Verify Calculator Operations
Scenario Outline: Verify addition of two numbers
#Given line states that the User is on the Calculator home page and Calculator page is displayed.
Given I am on Calculator page
#When step describes an action that User enters/clicks on a number
When I enter number <number>
#And step indicates clicking on a specific operator (like addition, subtraction, etc.) on the calculator
And I click on operator '<operator>'
#And Step follows the operator click by entering another number into the calculator.
And I enter number <number1>
#Then is the verification step where the test checks if the result displayed
Then I verify the result as <expectedResult>
Examples:
| number | operator | number1 | expectedResult |
| 5 | + | 2 | 7 |
| 9 | - | 3 | 6 |
| 6 | * | 4 | 24 |
| 2 | / | 2 | 1 |
2. Step Def File:
The step definition file serves as the bridge between actual feature file with the actual method implementation in the page file. The Calculator steps are a step definition file that maps the feature file to the page file and functional implementation.
package steps;
import core.TestContext;
import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.testng.Assert;
import pages.CalculatorPage;
import java.io.IOException;
public class CalculatorSteps extends TestContext {
public CalculatorSteps() {
//Here the constructor initializes a new instance of CalculatorPage,
// so the CalculatorSteps class can interact with the calculator web page through methods in the CalculatorPage class
calculatorPage = new CalculatorPage();
}
@Given("I am on Calculator page")
//Here we call the function from Calculator Page which is Sync with Feature file Given definition
public void iAmOnCalculatorPage() throws IOException {
calculatorPage.iAmOnCalculatorPage();
}
@When("I enter number {int}")
//Here also the function is called from page file and Sync with feature file When step
public void iEnterNumber(int number) {
calculatorPage.iEnterNumber(number);
}
@And("I click on operator {string}")
//Here also the function is called from page file and sync with feature file And step
public void iClickOnOperator(String operator) {
calculatorPage.iClickOnOperator(operator);
}
@Then("I verify the result as {int}")
//Here also the function is called from page file and synched with feature file Then step
public void iVerifyTheResultAs(int expectedResult) {
String actualResult = calculatorPage.iVerifyTheResultAs();
Assert.assertEquals(actualResult, String.valueOf(expectedResult));
}
}
3. Page File:
Page file, in addition, is actual code implementation from the step definition file.Here, we have saved all the actual methods and web page elements, thereby ensuring easy access and organization. It is basically POM structure. So here we are performing addition operation in Calculator we application so created a method to click on a number and another method for clicking on the operator. Here we can minimize the code by reusing the code as much as possible.
package pages;
import core.TestContext;
import utilities.ConfigUtil;
import java.io.IOException;
public class CalculatorPage extends TestContext {
public void iAmOnCalculatorPage() throws IOException {
page.navigate(ConfigUtil.getPropertyValue("base_url"));
}
public void iEnterNumber(int number) {
page.locator("//span[@onclick='r(" + number + ")']").click();
}
public void iClickOnOperator(String operator) {
page.locator("//span[@onclick=\"r('" + operator + "')\"]").click();
}
public String iVerifyTheResultAs() {
page.locator("//span[@onclick=\"r('=')\"]").click();
return page.locator("//div[@id='sciOutPut']").innerText().trim();
}
public void tearDown() {
page.close();
}
}
4. Hooks:
Hooks are setup and teardown methods that, therefore, are written separately in the configuration class. Here we have annotation declare in the hooks file @before and @After. Hooks are steps to be performed a before and after function of the feature file. In this we have open the Web browser in Before and After Tag. These are special functions which allows the testers to execute specific points during execution.
package core;
import core.TestContext;
import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;
import utilities.WebUtil;
public class Hooks extends TestContext {//Hooks class inherits the property of TestContext class
@Before //@Before Tag denotes that it should be executed before scenario
public void beforeScenario(Scenario scenario) {
page = WebUtil.initBrowser(); //this method initializes the browser session
}
@After //@After Tag denotes that it should be executed after scenario
public void afterScenario() {
WebUtil.tearDownPW();//this method is for tasks such as closing browser sessions
}
}
5. TestContext:
The TestContext class, moreover, holds various instances and variables required for test execution. In this context, we have successfully created a web driver instance, a page file instance, and a browser context. As a result, the code reusability, organization, and maintainability are improved here.
package core;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.Page;
import pages.CalculatorPage;
public class TestContext { //TestContext class, which acts as a container to store all instances for test framework
public static Page page;
//Refers to Playwright’s Page object. This controls a specific browser tab or page in a Playwright-based test
public static CalculatorPage calculatorPage;
//This stores an instance of the CalculatorPage object, representing the page object model (POM)
public static Browser browser;
//refers to Playwright's Browser instance, which represents the entire browser
}
6. TestRunner:
The Test Runner is responsible for discovering test cases, executing them, and reporting the results back; additionally, it provides the necessary infrastructure to execute the tests and manage the testing workflow. It also syncs the feature file with step file.
package core;
import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
import org.testng.annotations.DataProvider;
@CucumberOptions(features = "src/test/java/features", //the path where Cucumber feature files are located.
glue = {"steps", "core"}) //Cucumber where to find the step definitions (in the steps and core packages)
public class TestRunner extends AbstractTestNGCucumberTests {
//Above Etends which is a base class provided by Cucumber to run the tests with TestNG
@DataProvider //allows running multiple Cucumber scenarios as separate tests in TestNG
@Override
public Object[][] scenarios() {
return super.scenarios();
}//Calls the parent class method to return all the Cucumber scenarios in an array format for TestNG to run
}
7. WebUtils:
Web Utils is a file in which browser instance is created and playwright is initialised here. The code for web browser page launching is written here and for closing the browser instance. The page is extended by TestContext where all the properties of TestContext are given to WebUtils page.
package utilities;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import core.TestContext;
public class WebUtil extends TestContext {
public static Page initBrowser(){
//Initializes a browser session using Playwright's Chromium browser
Playwright playwright = Playwright.create(); //Creates an instance of Playwright
browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
page = browser.newPage(); //Creates a new page/tab within the launched browser
return page;
}
public static void tearDownPW() {
page.close();
} // It is called to close the current page/tag
}
This is the important file where we download all the dependencies required for the test execution. Also, it contains information of project and configuration information for the maven to build the project such as dependencies, build directory, source directory, test source directory, plugin, goals etc.
This are the dependencies required to download:
https://mvnrepository.com/artifact/io.cucumber/cucumber-java
https://mvnrepository.com/artifact/io.cucumber/cucumber-testng
https://mvnrepository.com/artifact/com.microsoft.playwright/playwright
Conclusion:
In this blog, we’ve discussed using the Java Playwright framework with Cucumber for BDD. Playwright offers fast, cross-browser testing and easy parallel execution, making it a great alternative to Selenium. Paired with Cucumber, it helps teams write clear, automated tests. Playwright’s debugging tools and test isolation also reduce test issues and maintenance, making it ideal for building reliable test suites for faster, higher-quality software delivery.
GitHub Link – https://github.com/spurqlabs/PlaywrightJavaBDD
Click here to read more blogs like this.