Maven for Selenium
Maven is the build tool behind most Java Selenium frameworks. It downloads Selenium, TestNG and every other library from one file (pom.xml), compiles your code, runs your suite with one command and gives CI servers like Jenkins a standard way to do the same. This guide gives you a working pom.xml, explains the lifecycle, and shows the commands you'll actually use.
What Maven Does for a Selenium Project
- Dependencies — declares Selenium, TestNG, reporting and data libraries and downloads them (plus their own dependencies) into
~/.m2/repository. - Standard structure — code in
src/main/java, tests insrc/test/java, resources insrc/test/resources. - One-command runs —
mvn testcompiles and runs the suite anywhere, including CI. - Reports for CI — Surefire writes XML results to
target/surefire-reports, which Jenkins reads.
A Working pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 1. Coordinates: who this project is -->
<groupId>com.shop</groupId>
<artifactId>shop-automation</artifactId>
<version>1.0.0</version>
<!-- 2. Properties: versions and settings in one place -->
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<selenium.version>4.25.0</selenium.version> <!-- use the latest from Maven Central -->
<testng.version>7.10.2</testng.version>
<suiteXmlFile>testng.xml</suiteXmlFile>
</properties>
<!-- 3. Dependencies: the libraries -->
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium.version}</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 4. Build: plugins -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/${suiteXmlFile}</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
<!-- 5. Profiles: alternative settings -->
<profiles>
<profile>
<id>smoke</id>
<properties>
<suiteXmlFile>smoke.xml</suiteXmlFile>
</properties>
</profile>
</profiles>
</project>
Add Extent Reports, Log4j2, Jackson or Apache POI as extra <dependency> blocks the same way. Since Selenium 4.6, Selenium Manager downloads browser drivers automatically — no WebDriverManager dependency needed.
The sections explained
| Section | Purpose |
|---|---|
groupId / artifactId / version |
The project's unique coordinates |
properties |
Java version, encoding, library versions — change them in one place |
dependencies |
Libraries; scope test means "only for test code" |
build / plugins |
How to compile, test and package — Surefire runs the tests |
profiles |
Named variations activated with -P (smoke, regression, grid) |
The Build Lifecycle
Maven's default lifecycle is an ordered list of phases. Running a phase runs every phase before it:
| Phase | What happens |
|---|---|
validate |
Checks the project is correct and complete |
compile |
Compiles src/main/java into target/classes |
test |
Compiles and runs tests in src/test/java with Surefire |
package |
Builds the JAR (or WAR) |
integration-test |
Runs integration tests (with the Failsafe plugin) |
verify |
Checks the results — Failsafe fails the build here |
install |
Copies the package into your local repository (~/.m2) |
deploy |
Uploads it to a remote repository |
There are two more lifecycles: clean (mvn clean deletes target/) and site (project documentation). mvn clean test runs the clean lifecycle, then the default lifecycle up to test.
mvn test vs mvn install
mvn test— compile and run the tests. This is what you run for a Selenium suite, locally and in CI.mvn install— also packages the project and installs it in~/.m2so other Maven projects can depend on it (for example, a shared framework library used by several test projects). It runs the tests on the way.
Commands You'll Actually Use
mvn clean test # full clean run with testng.xml
mvn test -Psmoke # use the smoke profile (smoke.xml)
mvn test -DsuiteXmlFile=regression.xml # choose a suite by property
mvn test -Dtest=LoginTest # one class
mvn test -Dtest=LoginTest#validLogin # one method
mvn test -Dgroups=smoke # one TestNG group
mvn test -Dbrowser=firefox -Denv=staging # values your ConfigReader reads with System.getProperty
mvn test -DskipTests # build without running tests
mvn dependency:tree # see every library and version (find conflicts)
mvn -U clean test # force re-download of updated dependencies
-Dname=value sets a system property that your framework reads with System.getProperty("browser") — the standard way to switch browsers and environments from CI without editing files.
Key Plugins
| Plugin | Role in a test project |
|---|---|
maven-surefire-plugin |
Runs the tests in the test phase — the most important one for Selenium |
maven-failsafe-plugin |
Runs integration tests in integration-test/verify |
maven-compiler-plugin |
Compiles Java (Java version via maven.compiler.release) |
maven-dependency-plugin |
Analyses dependencies (dependency:tree) |
maven-clean-plugin |
Deletes target/ |
Common Problems
| Symptom | Cause and fix |
|---|---|
| "Tests run: 0" | Test classes aren't named *Test, Test*, *Tests or *TestCase (Surefire's defaults), or they're in src/main/java — or suiteXmlFiles points to the wrong path |
Compilation errors about TestNG annotations in src/main/ |
TestNG has test scope — test code must live in src/test/java |
| Build passes but tests weren't run in CI | -DskipTests or a missing Surefire configuration |
NoSuchMethodError / ClassNotFoundException at runtime |
Version conflict between libraries — check mvn dependency:tree. See ClassNotFoundException vs NoClassDefFoundError |
-Dsurefire.suiteXmlFiles is ignored |
The POM already sets suiteXmlFiles; POM configuration wins — use a property like -DsuiteXmlFile as above |
Maven in CI
Continuous Integration means every commit is built and tested automatically. For a Selenium project the flow is:
push → CI checks out the code → mvn clean test -Denv=qa -Dheadless=true → publish target/surefire-reports/*.xml and the HTML report.
A failing test fails the Maven build, which fails the pipeline.
Full Jenkinsfile: The Complete Jenkins Tutorial; concepts: Jenkins Fundamentals & CI/CD.
See what happens inside the browser once Maven has started your tests in the Selenium WebDriver Visualizer.
From Real Projects
I've built and maintained test scripts in a hybrid framework — POM classes, a business library, TestNG and data from Excel through Apache POI. The rule that made it work: a test script describes the business flow, and all page details live in the POM classes, so a UI change means one fix instead of dozens. On Canolog, the many forms and screens across sales, inventory, finance and service are where keeping page details in POM classes and reusable steps in a business library paid off. Running the suite from the command line with Maven is the first step towards CI.
📚 Official documentation: Selenium documentation
FAQs
What is Maven?
A build and project-management tool for Java that manages dependencies through pom.xml, uses a standard project structure and runs builds and tests through a defined lifecycle.
What are the Maven lifecycle phases?
validate, compile, test, package, integration-test, verify, install, deploy — each phase runs all the ones before it. clean is a separate lifecycle.
mvn test vs mvn install?
mvn test compiles and runs the tests; mvn install also packages the project and installs it into the local repository for other projects to use.
Which plugin runs TestNG tests?
The Maven Surefire plugin, configured with suiteXmlFiles to point at your testng.xml.
How do you pass the browser or environment from the command line?
As system properties — mvn test -Dbrowser=firefox -Denv=staging — read in code with System.getProperty().
What is a Maven profile?
A named set of properties or configuration activated with -P, for example -Psmoke to run the smoke suite.