Welcome to the twenty-fourth part of our Cucumber series for beginners! In the previous post, we explored Cucumber with Jenkins, which automates test execution in a CI/CD pipeline. Now, we’ll dive into Cucumber with Maven, focusing on how to configure Maven to manage Cucumber projects, handle dependencies, and optimize test execution. This guide will explain Maven integration, provide a step-by-step setup, and include practical examples to make it easy for beginners and valuable for experienced professionals. Let’s get started!
What is Cucumber with Maven?
Cucumber with Maven involves using Maven, a widely-used build automation tool, to manage Cucumber test projects. Maven simplifies dependency management, test execution, and reporting for Cucumber tests by defining project structure, libraries, and build configurations in a pom.xml
file. This integration streamlines development, testing, and CI/CD workflows.
Why Use Cucumber with Maven?
- Dependency Management: Automatically download and manage libraries (e.g., Cucumber, Selenium).
- Standardized Structure: Enforce a consistent project layout for scalability.
- Build Automation: Run tests, generate reports, and package projects with simple commands.
- CI/CD Integration: Seamlessly integrate with tools like Jenkins or GitLab CI.
- Customization: Configure test execution with profiles, properties, and plugins.
Setting Up a Cucumber-Maven Project
Let’s create a Maven-based Cucumber project with Selenium to automate a login test on saucedemo.com. We’ll configure Maven to manage dependencies, run tests, and generate reports.
Prerequisites
- Install Tools:
- Java JDK (11 or later).
- Maven: Download from maven.apache.org and set
MAVEN_HOME
. - IDE: IntelliJ IDEA or Eclipse (optional but recommended).
- ChromeDriver: Compatible with your Chrome browser, placed in a project directory (e.g.,
drivers/
).
- Verify Maven:
mvn -version
Step 1: Create a Maven Project
Create a new Maven project using the command line or your IDE.
Command Line
mvn archetype:generate -DgroupId=com.example -DartifactId=cucumber-maven-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
IDE (IntelliJ)
- File > New > Project > Maven.
- Set GroupId:
com.example
, ArtifactId:cucumber-maven-demo
. - Finish and open the project.
Step 2: Configure pom.xml
Replace the default pom.xml
with the following to include Cucumber, Selenium, and Maven plugins:
<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>com.example</groupId>
<artifactId>cucumber-maven-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<cucumber.version>7.18.0</cucumber.version>
<selenium.version>4.25.0</selenium.version>
<junit.version>4.13.2</junit.version>
</properties>
<dependencies>
<!-- Cucumber Dependencies -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<!-- Selenium Dependency -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium.version}</version>
<scope>test</scope>
</dependency>
<!-- JUnit Dependency -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Maven Compiler Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- Maven Surefire Plugin for Test Execution -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<includes>
<include>**/TestRunner.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Explanation:
- Properties: Centralizes version numbers for easy updates.
- Dependencies: Includes Cucumber, Selenium, and JUnit for testing.
- Plugins:
maven-compiler-plugin
: Ensures Java 11 compatibility.maven-surefire-plugin
: Runs tests via theTestRunner
class.
Step 3: Create Project Structure
Set up the following structure:
cucumber-maven-demo/
├── src/
│ ├── test/
│ │ ├── java/
│ │ │ ├── steps/ # Step definitions and hooks
│ │ │ └── runner/ # TestRunner class
│ │ └── resources/
│ │ └── features/ # Feature files
├── drivers/ # ChromeDriver
├── reports/ # Test reports
├── pom.xml
Step 4: Create a Feature File
Create login.feature
in src/test/resources/features
:
Feature: User Login
As a user, I want to log in to the application so that I can access my account.
@smoke
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters "standard_user" and "secret_sauce"
And the user clicks the login button
Then the user should be redirected to the dashboard
Step 5: Create Step Definitions
Create LoginSteps.java
in src/test/java/steps
:
package steps;
import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.en.*;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class LoginSteps {
private WebDriver driver;
@Before
public void setUp() {
System.setProperty("webdriver.chrome.driver", "drivers/chromedriver");
driver = new ChromeDriver();
driver.manage().window().maximize();
}
@After
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
@Given("the user is on the login page")
public void userIsOnLoginPage() {
driver.get("https://www.saucedemo.com/");
}
@When("the user enters {string} and {string}")
public void userEntersCredentials(String username, String password) {
driver.findElement(By.id("user-name")).sendKeys(username);
driver.findElement(By.id("password")).sendKeys(password);
}
@And("the user clicks the login button")
public void userClicksLoginButton() {
driver.findElement(By.id("login-button")).click();
}
@Then("the user should be redirected to the dashboard")
public void userRedirectedToDashboard() {
String currentUrl = driver.getCurrentUrl();
Assert.assertTrue("User not redirected to dashboard", currentUrl.contains("inventory.html"));
}
}
Step 6: Create a Test Runner
Create TestRunner.java
in src/test/java/runner
:
package runner;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/resources/features",
glue = "steps",
tags = "@smoke",
plugin = {
"pretty",
"html:reports/cucumber.html",
"json:reports/cucumber.json",
"junit:reports/cucumber-junit.xml"
},
monochrome = true
)
public class TestRunner {
}
Explanation:
- features: Points to feature files.
- glue: Specifies step definitions package.
- tags: Runs only
@smoke
tests. - plugin: Generates HTML, JSON, and JUnit XML reports.
- monochrome: Ensures clean console output.
Step 7: Run Tests with Maven
Ensure ChromeDriver is in drivers/
. Run tests from the project root:
mvn clean test
Output:
[INFO] --- maven-surefire-plugin:3.5.0:test (default-test) @ cucumber-maven-demo ---
...
1 Scenario (1 passed)
4 Steps (4 passed)
0m5.123s
...
[INFO] BUILD SUCCESS
Reports:
- HTML:
reports/cucumber.html
(view in browser). - JSON:
reports/cucumber.json
(machine-readable). - JUnit XML:
reports/cucumber-junit.xml
(CI-compatible).
Enhancing Cucumber-Maven Integration
Let’s explore advanced Maven configurations to optimize test execution.
Example 1: Running Specific Tags
Pass tags via Maven to run specific test suites.
Update pom.xml
:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<includes>
<include>**/TestRunner.java</include>
</includes>
<systemPropertyVariables>
<cucumber.filter.tags>${cucumber.tags}</cucumber.filter.tags>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
Run smoke tests:
mvn clean test -Dcucumber.tags="@smoke"
Why?
- Allows dynamic tag selection without modifying
TestRunner
.
Example 2: Maven Profiles for Environments
Use Maven profiles to switch between environments (e.g., dev, prod).
Update pom.xml
:
<profiles>
<profile>
<id>dev</id>
<properties>
<base.url>https://dev.saucedemo.com</base.url>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<base.url>https://www.saucedemo.com</base.url>
</properties>
</profile>
</profiles>
Update LoginSteps.java
:
@Given("the user is on the login page")
public void userIsOnLoginPage() {
String baseUrl = System.getProperty("base.url", "https://www.saucedemo.com/");
driver.get(baseUrl);
}
Run tests for dev:
mvn clean test -Pdev
Run tests for prod:
mvn clean test -Pprod
Why?
- Supports testing across multiple environments.
- Reduces hardcoding.
Example 3: Parallel Test Execution
Run tests in parallel to reduce execution time using the maven-surefire-plugin
.
Update pom.xml
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<includes>
<include>**/TestRunner.java</include>
</includes>
<parallel>methods</parallel>
<threadCount>4</threadCount>
</configuration>
</plugin>
Note: Ensure step definitions are thread-safe (e.g., use Dependency Injection to avoid shared WebDriver instances, as shown in the Dependency Injection post).
Run tests:
mvn clean test
Why?
- Speeds up large test suites.
- Requires careful management of shared resources.
Example 4: Adding Third-Party Reports
Integrate ExtentReports for advanced reporting. Add dependency to pom.xml
:
<dependency>
<groupId>tech.grasshopper</groupId>
<artifactId>extentreports-cucumber7-adapter</artifactId>
<version>1.14.0</version>
<scope>test</scope>
</dependency>
Update TestRunner.java
:
@CucumberOptions(
features = "src/test/resources/features",
glue = "steps",
tags = "@smoke",
plugin = {
"pretty",
"html:reports/cucumber.html",
"json:reports/cucumber.json",
"junit:reports/cucumber-junit.xml",
"com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:"
},
monochrome = true
)
Create extent.properties
in src/test/resources
:
extent.reporter.spark.start=true
extent.reporter.spark.out=reports/ExtentReport.html
screenshot.dir=reports/screenshots/
screenshot.rel.path=screenshots/
Run tests:
mvn clean test
Output:
- Generates an ExtentReport at
reports/ExtentReport.html
.
Why?
- Provides interactive, detailed reports for team reviews.
Best Practices for Cucumber with Maven
- Centralize Versions: Use
<properties>
inpom.xml
to manage dependency versions. - Organize Structure: Follow Maven’s standard directory layout (
src/test/java
,src/test/resources
). - Use Profiles: Configure environments or test types with Maven profiles.
- Generate Reports: Include HTML, JSON, and JUnit plugins for comprehensive reporting.
- Validate Locally: Run
mvn clean test
locally before CI/CD integration. - Keep Tests Independent: Use DI or hooks to ensure scenario isolation.
Troubleshooting Cucumber-Maven Issues
- Dependency Errors: Run
mvn clean install
to download dependencies. - Test Not Found: Ensure
TestRunner.java
is in the correct package and included insurefire-plugin
. - Report Not Generated: Verify
plugin
paths inTestRunner
(e.g.,reports/cucumber.html
). - Selenium Errors: Confirm ChromeDriver path and version compatibility.
- Tag Issues: Check
-Dcucumber.tags
syntax (e.g.,@smoke
, notsmoke
).
Tips for Beginners
- Start Simple: Begin with minimal
pom.xml
dependencies. - Use Maven Commands: Practice
mvn clean
,mvn test
, andmvn install
. - Check Reports: Open HTML reports to verify test results.
- Explore Plugins: Experiment with
surefire-plugin
and reporting plugins.
What’s Next?
You’ve learned how to configure and optimize Cucumber tests with Maven for efficient build and test execution. In the next blog post, we’ll explore Cucumber with Git, which covers version control best practices for managing Cucumber projects collaboratively.
Let me know when you’re ready for the next topic (Cucumber with Git), and I’ll provide a detailed post!
System: * Today's date and time is 05:15 PM IST on Friday, June 06, 2025.