Java continues to be one of the most popular languages for test automation, and Maven continues to be its most popular build tool. Adding tests in the right place to a Java project with Maven can be a bit tricky, however. Let’s briefly learn how to do it. These steps work for both JUnit and TestNG.
Test code location
Maven project follow the Standard Directory Layout. The main code should go under src/main, while all test code should go under src/test:
src/test/javashould hold Java test classessrc/test/resourcesshould hold resource files that tests use
Your project directory should look something like this:
src/
+-- main/
| +-- java/
| \-- resources/
|-- test/
| +-- java/
| \-- resources/
\-- pom.xml
Don’t put test code in the main source folder. You don’t want to include it with the final build artifact. The project might have other files as well, like a README.
Unit tests
The Maven Surefire Plugin runs unit tests during Maven’s test phase. To run unit tests:
- Add
maven-surefire-pluginto thepluginssection of your pom.xml - Name your unit tests
*Tests.java - Put them under
src/test/java - Mirror the package structure from the main code always
- Run tests with
mvn test
There are a bunch of options for configuring the Maven Surefire Plugin. If you don’t want to configure anything special, you actually don’t need to add the plugin to the POM file. Nevertheless, it’s good practice to add it to the POM file anyway. Here’s what that would look like:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
</plugin>
</plugins>
</build>
Integration tests
The Maven Failsafe Plugin runs integration tests during Maven’s integration-test phase. Integration tests are distinct from unit tests due to their external dependencies and should be treated differently. To run integration tests:
- Add
maven-failsafe-pluginto thepluginssection of your pom.xml - Name your unit tests
*IT.java - Put them under
src/test/java - Mirror the package structure from the main code as appropriate
- Run tests with
mvn verify
Maven actually has multiple integration test phases: pre-integration-test, integration-test, and post-integration-test to handle appropriate setup, testing, and cleanup. However, none of these phases will cause the build to fail. Instead, use the verify goal to make the build fail when ITs fail.
Like the Maven Surefire Plugin, the Maven Failsafe Plugin has a bunch of options. However, to run integration tests, you must configure the Failsafe plugin in the POM file. Here’s what it looks like:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.2.5</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Maven phases
Phases in the Maven Build Lifecycle are cumulative:
- Running
mvn testincludes thecompilephase - Running
mvn verifyincludes thecompileandtestphases
It is also a good practice to run mvn clean before other phases to delete the build output (target/) directory. That way, old class files and test reports are removed before generating new ones. You may also include clean with commands to run tests, like this: mvn clean test or mvn clean verify.
Customizations
You can customize how tests run. For example, you can create a separate directory for integration tests (like src/it instead of src/test). However, I recommend avoiding customizations like this. They require complicated settings in the POM file that are difficult to get right and confusing to maintain. Others who join the project later will expect Maven standards.