Building a Hybrid TestNG-Cucumber Framework (Part 7)


Welcome to Part 7 of our Selenium Framework Design! In this guide, we’ll learn to integrate Cucumber into our existing TestNG framework to create a hybrid TestNG-Cucumber framework. We’ll cover Gherkin syntax, feature files, step definitions, Cucumber tags, and data-driven testing, enabling our framework to support both TestNG and Cucumber tests. By the end, you’ll have a robust, business-readable automation framework ready for CI integration. Let’s get started!
Why Cucumber?
Cucumber is a Behavior-Driven Development (BDD) framework that allows test cases to be written in plain English using Gherkin syntax, making them understandable to non-technical stakeholders like business analysts (BAs). While TestNG provides features like groups, retry mechanisms, and reporting, Cucumber offers similar capabilities but with a focus on business-readable test cases. In this course, we won’t rewrite our framework from scratch using only Cucumber. Instead, we’ll build a hybrid framework, adding Cucumber on top of our existing TestNG framework to support both TestNG and Cucumber tests. This approach demonstrates how to leverage Cucumber’s high-level concepts while reusing our existing POM, BaseTest, and other components.
Scope of Part 7
Understand Cucumber terminology (Gherkin, feature files, scenarios, step definitions, tags, scenario outlines).
Integrate Cucumber into our TestNG framework.
Write feature files for existing tests (e.g., SubmitOrderTest, ErrorValidationTest).
Create step definitions to map Gherkin steps to our Selenium code.
Use Cucumber tags to control test execution (similar to TestNG groups).
Implement data-driven testing with scenario outlines.
Run Cucumber tests via a TestNG runner and integrate with Maven and Jenkins.
This guide assumes your project is a Maven project in Eclipse, with TestNG suites (testng.xml
, Purchase.xml
, ErrorValidation.xml
) and the framework from Parts 1–6.
Part 1: Understanding Cucumber Terminology
What is Gherkin?
Gherkin is a business-readable, domain-specific language used to describe software behavior in a structured format. Unlike plain English test cases, which can be ambiguous (e.g., “Popup message is displayed when buttons are clicked and errors are gone” can be interpreted differently by BAs, QAs, and developers), Gherkin uses a standardized syntax to avoid misinterpretation. It defines test cases (called scenarios) using keywords like Given, When, Then, And, and But, ensuring clarity across teams.
Example of Ambiguity in Plain English:
Suppose a BA writes: “Popup message is displayed when buttons are clicked and errors are gone.”
BA’s Interpretation: Clicking a button shows a popup and clears errors.
QA’s Interpretation: Click a button only after ensuring no errors, then verify the popup.
This ambiguity can lead to misaligned development and testing, causing defects. Gherkin resolves this by enforcing a clear structure.
Key Cucumber Concepts
Scenario:
A scenario is a test case written in Gherkin syntax.
Example: Testing a credit card payment with minimum due amount.
Structure:
Scenario: Make minimum due amount credit card payment Given User is on the Pay Credit Card page When User fills all details And User selects minimum amount option And User clicks on Pay button Then Credit card confirmation page is displayed
Given: Defines preconditions (e.g., navigating to a page).
When: Describes user actions (e.g., filling details, clicking buttons).
Then: Specifies expected outcomes (e.g., confirmation page display).
And: Adds more actions or validations (positive statements).
But: Adds negative validations (e.g., “But error message is not displayed”).
Feature:
A feature represents a high-level business requirement (e.g., “Credit card payment functionality”).
Multiple scenarios validate a single feature.
Example:
Feature: Credit card payment Scenario: Make minimum due amount payment # Steps... Scenario: Pay statement balance # Steps... Scenario: Pay invalid amount (negative test) # Steps...
Feature File:
A file with a
.feature
extension that contains a feature and its scenarios.Acts like a TestNG test suite, grouping multiple scenarios (test cases).
Example: payment.feature contains all credit card payment scenarios.
Step Definition:
A Java class that maps Gherkin steps to executable Selenium code.
Each Gherkin step (e.g., “Given User is on the Pay Credit Card page”) is linked to a Java method using annotations like
@Given
,@When
,@Then
Example:
@Given("User is on the Pay Credit Card page") public void navigateToPayCreditCardPage() { // Selenium code to navigate to the page }
Scenario Outline:
Similar to a scenario but supports data-driven testing using an Examples table.
Replaces TestNG’s
@DataProvider
for parameterization.Example:
Scenario Outline: Verify word palindrome Given I enter word <word> Then The output should be <result> Examples: | word | result | | refer | true | | test | false |
The scenario runs for each row in the Examples table, substituting
<word>
and<result>
.
Background:
A set of steps executed before every scenario in a feature file, similar to TestNG’s
@BeforeMethod
.Example: Navigating to the e-commerce homepage before each test.
Tags:
- Labels (e.g.,
@Regression
,@Smoke
) used to group and selectively run scenarios, similar to TestNG groups.
- Labels (e.g.,
Why Use Cucumber?
Business-Readable: Non-technical stakeholders (e.g., BAs) can understand and contribute to test cases.
Reusability: Steps can be reused across scenarios, reducing code duplication.
Clarity: Gherkin’s structured syntax eliminates ambiguity.
Hybrid Framework: Combines Cucumber’s readability with TestNG’s robustness, allowing both plain Java TestNG tests and Cucumber tests.
Part 2: Setting Up Cucumber in the Project
Step 1: Add Cucumber Dependencies
To integrate Cucumber, add the necessary dependencies to pom.xml.
Go to Maven Repository:
Visit mvnrepository.com.
Search for:
Cucumber Java: For core Cucumber functionality.
Cucumber TestNG: For running Cucumber with TestNG.
Copy the latest stable versions (e.g., 7.8.0).
Update pom.xml:
Add the dependencies:
<dependencies> <!-- Existing dependencies (Selenium, TestNG, etc.) --> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> <version>7.8.0</version> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-testng</artifactId> <version>7.8.0</version> </dependency> </dependencies>
Verify Dependencies:
- Save
pom.xml
and ensure Maven downloads the dependencies (refresh the project in Eclipse).
- Save
Step 2: Install Cucumber Eclipse Plugin
To support writing feature files with proper syntax highlighting:
Open Eclipse Marketplace:
Go to Help > Eclipse Marketplace.
Search for “Cucumber Eclipse Plugin” and install it.
Restart Eclipse after installation.
Purpose:
- The plugin provides syntax highlighting and auto-suggestions for Gherkin keywords (e.g., Feature, Scenario, Given) in
.feature
files.
- The plugin provides syntax highlighting and auto-suggestions for Gherkin keywords (e.g., Feature, Scenario, Given) in
Part 3: Creating Feature Files
We’ll convert our existing TestNG tests (SubmitOrderTest
and ErrorValidationTest
) into Cucumber feature files, reusing our POM classes.
Step 1: Create a Feature File for SubmitOrderTest
Create a Package:
- In
src/test/java
, create a new package:cucumber
- In
Create Feature File:
Right-click the cucumber package > New > File.
Name it SubmitOrder.feature with a
.feature
extension.The Cucumber plugin provides a template with Gherkin syntax.
Write the Feature File:
Map the
SubmitOrderTest
test case (login, add product to cart, checkout, submit order, verify confirmation) to Gherkin.Use a Scenario Outline for data-driven testing.
Add a Background for the prerequisite step (launching the application).
Example:
Feature: Purchase the order from Ecommerce website Background: Given I landed on Ecommerce page Scenario Outline: Positive test of submitting the order Given I logged in with username <name> and password <password> When I add product <productName> to cart And checkout <productName> and submit the order Then "THANK YOU FOR THE ORDER." message is displayed on Confirmation page Examples: | name | password | productName | | samikshak@gmail.com | Sam@12345 | ZARA COAT 3 |
Explanation:
Feature: Describes the business requirement (purchasing an order).
Background: Runs before each scenario, launching the e-commerce page (similar to
launchApplication
in BaseTest).Scenario Outline: Defines the test with placeholders (
<name>
,<password>
,<productName>
) for data-driven testing.Examples: Provides test data, similar to TestNG’s
@DataProvider
.Steps:
Given: Logs in with username and password from the Examples table.
When/And: Adds a product to the cart and submits the order.
Then: Verifies the confirmation message (static text in quotes).
Step 2: Create Step Definitions
Create a Step Definitions Package:
- In src/test/java, create a package:
stepDefinitions
- In src/test/java, create a package:
Create a Step Definition Class:
Right-click the stepDefinitions package > New > Class.
Name it
StepImplementation.java
Implement Steps:
Map each Gherkin step to a Java method using Cucumber annotations (
@Given
,@When
,@Then
).Reuse existing POM classes and BaseTest methods.
Example:
package stepdefinitions; import java.io.IOException; import org.testng.Assert; 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 pageobjects.CartPage; import pageobjects.CheckoutPage; import pageobjects.ConfirmationPage; import pageobjects.LandingPage; import pageobjects.ProductCatalogue; import testComponents.BaseTest; public class StepImplementation extends BaseTest { public LandingPage landingPage; public ProductCatalogue productCatalogue; public ConfirmationPage confirmationPage; @Given("I Landed on Ecommerce page") public void i_landed_on_Ecommerce_page() throws IOException { landingPage = launchApplication(); } @Given("^Logged in with username (.+) and password (.+)$") public void logged_in_with_username_and_password(String email, String password) { productCatalogue = landingPage.loginApplication(email, password); } @When("^I add (.+) to Cart$") public void i_add_product_to_cart(String productName) throws InterruptedException { productCatalogue.getProducList(); productCatalogue.addProductToCart(productName); } @And("^Checkout (.+) and submit the order$") public void checkout_and_submit_the_order(String productName) throws InterruptedException { CartPage cartPage = productCatalogue.goToCartPage(); boolean match = cartPage.verifyProductIsDisplayed(productName); Assert.assertTrue(match); CheckoutPage checkoutPage = cartPage.goToCheckOutPage(); checkoutPage.selectCountry("india"); confirmationPage = checkoutPage.submitOrder(); } @Then("{string} message is displayed on ConfirmationPage") public void message_is_displayed_on_ConfirmationPage(String string) { String confirmMessage = confirmationPage.verifyConfirmationMessage(); Assert.assertTrue(confirmMessage.equalsIgnoreCase(string)); driver.close(); } @Then("{string} message is displayed") public void something_message_is_displayed(String string) { Assert.assertEquals(string, landingPage.getErrorMessage()); driver.close(); } }
Explanation:
Inheritance: Extends
BaseTest
to reuselaunchApplication
and WebDriver setup.Global Variables:
LandingPage
,ProductCatalogue
, andConfirmationPage
are declared globally to maintain state across steps.Annotations:
@Given("I Landed on Ecommerce page")
: Sets up the initial state by launching the application.@Given("^Logged in with username (.+) and password (.+)$")
: Uses regular expressions with(.+)
to capture any username/password values from test data.@When("^I add (.+) to Cart$")
: Captures any product name and adds it to the shopping cart.@And("^Checkout (.+) and submit the order$")
: Handles the checkout process for any specified product.@Then
steps: Verify expected results like confirmation messages or error messages.
Dynamic Parameters: Uses
(.+)
and{string}
patterns to capture different values (like usernames, passwords, product names) from the test scenarios, making tests reusable with different data.Assertions: Use TestNG’s Assert to verify outcomes.
Driver Cleanup:
driver.close()
ensures the browser closes after each test.
Step 3: Create a Test Runner
To run the feature file, create a TestNG runner class.
Create Runner Class:
- In
src/test/java/cucumber
, create a class:TestNGTestRunner.java
- In
Configure Cucumber Options:
Example:
package cucumber; import io.cucumber.testng.AbstractTestNGCucumberTests; import io.cucumber.testng.CucumberOptions; @CucumberOptions( features = "src/test/java/cucumber", glue = "stepDefinitions", monochrome = true, plugin = {"html:target/cucumber.html"} ) public class TestNGTestRunner extends AbstractTestNGCucumberTests { }
Explanation:
@CucumberOptions
:features: Path to the feature files (src/test/java/cucumber).
glue: Path to the step definitions package (stepDefinitions).
monochrome = true: Ensures readable console output.
plugin: Generates an HTML report at target/cucumber.html.
extends AbstractTestNGCucumberTests
: Enables Cucumber to run with TestNG, supporting TestNG assertions in step definitions.
Run the Test:
Right-click TestNGTestRunner.java > Run As > TestNG Test.
Cucumber scans the cucumber package, runs SubmitOrder.feature, maps steps to
StepImplementation.java
, and executes the test.Output:
The test logs in, adds “ZARA COAT 3” to the cart, checks out, submits the order, and verifies the confirmation message.
An HTML report is generated at
target/cucumber.html
Step 4: Create Feature File for ErrorValidationTest
Create Feature File:
In src/test/java/cucumber, create ErrorValidations.feature.
Example:
Feature: "Error Validation" This is feature description @ErrorValidation: Scenario Outline: Positive Test of Submitting the Order Given I Landed on Ecommerce page When Logged in with username <name> and password <password> Then "Incorrect email or password." message is displayed Examples: | name | password | | wrong_email@gmail.com | Sam@12345 |
Explanation:
Feature: Validates error handling (e.g., incorrect login credentials).
Scenario Outline: Tests login with incorrect credentials.
No Background: Reuses the “I landed on Ecommerce page” step directly.
Examples: Provides invalid credentials to trigger the error message.
Add Step Definition:
In
StepImplementation.java
, add the new step (reuse existing steps for landing and login):@Then("{string} message is displayed") public void error_message_displayed(String message) { Assert.assertEquals(landingPage.getErrorMessage(), message); driver.close(); }
Explanation:
Maps to “Then Incorrect email or password. message is displayed”.
Uses {string} to capture the error message.
Verifies the error message on the LandingPage and closes the browser.
Run the Test:
Running
TestNGTestRunner
executes bothSubmitOrder.feature
andErrorValidations.feature
(all feature files in the cucumber package).Result: The error validation test fails (as expected) due to incorrect credentials, and the report shows the outcome.
Part 4: Using Cucumber Tags
Tags control which scenarios to run, similar to TestNG groups.
Add Tags:
Update the feature files:
@Regression Feature: Purchase the order from Ecommerce website # ... (SubmitOrder.feature content)
@ErrorValidation Feature: Error validation on Ecommerce website # ... (ErrorValidations.feature content)
Update Test Runner:
Modify
TestNGTestRunner.java
to run only specific tags:@CucumberOptions( features = "src/test/java/cucumber", glue = "stepDefinitions", monochrome = true, tags = "@Regression", plugin = {"html:target/cucumber.html"} ) public class TestNGTestRunner extends AbstractTestNGCucumberTests { }
Explanation:
tags = "@Regression"
: Runs only scenarios/features with the@Regression
tag (i.e.,SubmitOrder.feature
).In newer Cucumber versions, use
tags = "@Regression"
(not{@Regression}
).
Run the Test:
Right-click TestNGTestRunner.java > Run As > TestNG Test.
Result: Only SubmitOrder.feature runs, skipping ErrorValidations.feature.
Part 5: Integrating with Maven and Jenkins
To run Cucumber tests via Maven and Jenkins, add a new profile to pom.xml.
Update pom.xml:
Add a
CucumberTests
profile:<profiles> <!-- Existing profiles (Regression, Purchase, ErrorValidation) --> <profile> <id>CucumberTests</id> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M5</version> <configuration> <includes> <include>**/TestNGTestRunner.java</include> </includes> </configuration> </plugin> </plugins> </pluginManagement> </build> </profile> </profiles>
Explanation:
<includes>
: Specifies the TestNGTestRunner.java file to run (unlike TestNG XML files in previous profiles).**/
searches all folders for TestNGTestRunner.java.
Run via Maven:
Open a terminal, navigate to the project root, and run:
mvn test -PCucumberTests
Result: Executes TestNGTestRunner, running feature files based on the tags filter (e.g.,
@Regression
).
Update Jenkins Job:
Open the existing Jenkins job (from Part 6).
Go to Configure > Build > Invoke top-level Maven targets.
Add the new profile:
test -PCucumberTests
Alternatively, parameterize the profile (as in Part 6):
Add a Choice Parameter named profile with options: Regression, Purchase, ErrorValidation, CucumberTests.
Update the Maven command to
test -P"$profile"
.
Save and run the job with
profile=CucumberTests
.Result: Jenkins runs the Cucumber tests, generating the
cucumber.html
report in the target folder.
Part 6: Key Differences Between TestNG and Cucumber
TestNG Features Not Supported in Cucumber:
@DataProvider
: Use Scenario Outline with Examples instead.TestNG groups: Use Cucumber tags.
TestNG XML suites: Use feature files and the TestNG runner.
Why Use TestNG Runner?:
Cucumber requires a runner (TestNG or JUnit) to execute feature files.
Since our framework uses TestNG assertions, we extend
AbstractTestNGCucumberTests
for compatibility.
Reusability:
Cucumber steps (e.g., “I landed on Ecommerce page”) are reusable across feature files, reducing code duplication.
The same POM classes (e.g.,
LandingPage
,ProductCatalogue
) are reused, maintaining framework consistency.
Key Takeaways
Cucumber Basics:
Gherkin: A structured language for business-readable test cases.
Feature Files: Contain scenarios (test cases) and act as test suites.
Step Definitions: Map Gherkin steps to Selenium code.
Scenario Outline: Enables data-driven testing with Examples.
Hybrid Framework:
Added Cucumber to the existing TestNG framework, reusing POM and BaseTest.
Created feature files for
SubmitOrderTest
andErrorValidationTest
.Used a TestNG runner (
AbstractTestNGCucumberTests
) to execute Cucumber tests.
Tags:
- Used
@Regression
and@ErrorValidation
to selectively run tests, similar to TestNG groups.
- Used
Maven and Jenkins:
Added a
CucumberTests
profile to runTestNGTestRunner
via Maven.Integrated with Jenkins for CI execution.
Reporting:
- Generated basic Cucumber HTML reports (
target/cucumber.html
).
- Generated basic Cucumber HTML reports (
Check out the complete code repository below:
Happy automating!
Subscribe to my newsletter
Read articles from Samiksha Kute directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Samiksha Kute
Samiksha Kute
Passionate Learner!