This tutorial will guide you through the process of running Unit Tests and Integration Tests separately in a Maven-based Spring Boot application. We will use the JUnit Tag feature to group our test cases and separate Unit Tests from Integration Tests.
To learn more, check out the Test Java code tutorials page.
Create your tests
In this tutorial, we will be grouping our tests into Unit Tests and Integration Tests. A Unit Test is a type of test that focuses on a small, isolated part of your application, typically a single function or method. On the other hand, an Integration Test checks the interactions between different parts of your application, such as service calls or data integrations.
By convention, we will name our test classes following this pattern:
- Unit Tests:
*Test.java
- Integration Tests:
*IntegrationTest.java
For example, you might have UserServiceTest.java
as a Unit Test, and UserServiceIntegrationTest.java
as an Integration Test.
Tag your tests
With JUnit Jupiter, you can tag your test methods or test classes using the @Tag
annotation. We will use the tags “Unit” for Unit Tests, and “Integration” for Integration Tests.
Example for Unit Test:
import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @Tag("Unit") public class UserServiceTest { @Test void someUnitTest() { // Your test code here } }
Example for Integration Test:
import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @Tag("Integration") public class UserServiceIntegrationTest { @Test void someIntegrationTest() { // Your test code here } }
Configure Maven to run Unit tests and Integration tests separately
To tell Maven how to run Unite tests separately from Integration tests, we will define some configurations in the pom.xml
file of our project. The key here is to use the maven-surefire-plugin
for Unit Tests, and the maven-failsafe-plugin
for Integration Tests.
Here is how our pom.xml
file looks:
<?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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.appsdeveloperblog</groupId> <artifactId>RunTestsSeparately</artifactId> <version>0.0.1-SNAPSHOT</version> <name>RunTestsSeparately</name> <description>Run Integration Tests separate from Unit Tests</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.2</version> <configuration> <skip>true</skip> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>2.22.2</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <profiles> <profile> <id>unit-tests</id> <activation> <activeByDefault>true</activeByDefault> </activation> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.2</version> <configuration> <skip>false</skip> <groups>Unit</groups> </configuration> </plugin> </plugins> </build> </profile> <profile> <id>integration-tests</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>2.22.2</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> <configuration> <skip>false</skip> <includes> <include>**/*IntegrationTest.java</include> </includes> </configuration> </plugin> </plugins> </build> </profile> </profiles> </project>
Let’s delve deeper into the <build>
and <profiles>
sections of the pom.xml
file.
<build>
Section:The<build>
section is where you can configure project build settings, like directory structure and build plugins.Here, you are using two plugins:maven-surefire-plugin
andmaven-failsafe-plugin
.maven-surefire-plugin
: This plugin is used during the test phase of the build lifecycle to execute the unit tests of an application. It is invoked when you run the commandmvn test
.maven-failsafe-plugin
: This plugin is designed to run integration tests while ensuring that failures do not halt the build. It is typically used with themvn verify
command.
In your
<build>
configuration, you’ve set<skip>true</skip>
for themaven-surefire-plugin
, meaning that by default, the unit tests will not be executed during the build. Themaven-failsafe-plugin
is configured without a skip option, meaning the integration tests will be run unless specified otherwise.<profiles>
Section:Maven profiles are a set of configuration values which can be used to set or override default values of Maven build. They are typically used for different build environments (like production, development, etc.), but here you are using them to separate the execution of unit tests from integration tests.You have two profiles:unit-tests
andintegration-tests
.unit-tests
: This profile reactivates themaven-surefire-plugin
by setting<skip>false</skip>
, and it specifies that only tests tagged with “Unit” should be included in the run. This profile isactiveByDefault
, meaning it will be used when no profiles are explicitly activated.integration-tests
: This profile configures themaven-failsafe-plugin
to include any test classes that end withIntegrationTest.java
in the name.
So, when you run mvn test
, Maven activates the unit-tests
profile by default and runs only the unit tests.
When you run mvn verify -Pintegration-tests
, Maven activates the integration-tests
profile and runs only the integration tests.
This configuration allows you to run your unit and integration tests separately, giving you more control over your testing strategy.
Run your tests
Now that our Maven configuration is set up, we can run our tests separately.
Running Unit Tests
To run Unit Tests, use the following command in the terminal:
mvn test
Running Integration Tests
To run Integration Tests, use the following command:
mvn verify -Pintegration-tests
Note that when we run the Integration Tests, the Unit Tests are skipped, because we have configured our pom.xml file that way.
Conclusion
Congratulations on reaching the end of this tutorial! Let’s recap the key takeaways from this learning journey:
- Test Annotations: You’ve learned how to use JUnit 5’s
@Tag
annotation to distinguish between unit tests and integration tests, helping to keep your test cases organized. - Maven Profiles: You now know how to use Maven profiles to control which tests get run during your build process. The
unit-tests
andintegration-tests
profiles you’ve set up make running separate tests a breeze. - Maven Plugins: You’ve seen how the
maven-surefire-plugin
andmaven-failsafe-plugin
can be configured to handle unit tests and integration tests, respectively. - Running Tests: You’re now able to run unit tests and integration tests separately in a Maven-based Spring Boot application, giving you more flexibility and control over your testing strategy.
With these skills, you’ve taken your understanding of testing in Spring Boot to the next level.
Interested in digging deeper into testing in Java? Be sure to check out our Test Java code tutorials page for more helpful guides and insights. Happy coding!