Master the most popular testing framework for Java, through the Learn JUnit course:
Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.
Get started with mocking and improve your application tests using our Mockito guide:
Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.
Get started with understanding multi-threaded applications with our Java Concurrency guide:
Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:
Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.
But these can also be overused and fall into some common pitfalls.
To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:
Get started with Spring and Spring Boot, through the Learn Spring course:
>> LEARN SPRINGExplore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:
Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.
I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.
You can explore the course here:
Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.
Get started with Spring Data JPA through the guided reference course:
Refactor Java code safely β and automatically β with OpenRewrite.
Refactoring big codebases by hand is slow, risky, and easy to put off. Thatβs where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.
Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions β one for newcomers and one for experienced users. Youβll see how recipes work, how to apply them across projects, and how to modernize code with confidence.
Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.
1. Overview
Itβs very common to execute all our JUnit tests automatically as a part of the CI build using Maven. This, however, is often time-consuming.
Therefore, we often want to filter our tests and execute either unit tests or integration tests or both at various stages of the build process.
In this tutorial, weβll look at a few filtering techniques for test cases with JUnit 5. In the following sections, weβll also look at various filtering mechanisms before JUnit 5.
2. JUnit 5 Tags
2.1. Annotating JUnit Tests with Tag
With JUnit 5 we can filter tests by tagging a subset of them under a unique tag name. For example, suppose we have both unit tests and integration tests implemented using JUnit 5. We can add tags on both sets of test cases:
@Test
@Tag("IntegrationTest")
public void testAddEmployeeUsingSimpelJdbcInsert() {
}
@Test
@Tag("UnitTest")
public void givenNumberOfEmployeeWhenCountEmployeeThenCountMatch() {
}
Henceforth we can execute all tests under a particular tag name separately. We can also tag the class instead of methods. Thereby including all tests in a class under a tag.
In the next few sections, weβll see various ways of filtering and executing the tagged JUnit tests.
2.2. Filtering Tags with Test Suite
JUnit 5 allows us to implement test suites through which we can execute tagged test cases:
@SelectPackages("com.baeldung.tags")
@IncludeTags("UnitTest")
public class EmployeeDAOUnitTestSuite {
}
Now, if we run this suite, all JUnit tests under the tag UnitTest would be executed. Similarly, we can exclude tests with ExcludeTags annotation.
2.3. Filtering Tags with Maven Surefire Plugin
For filtering JUnit tests within the various phases of the Maven build, we can use the Maven Surefire plugin. The Surefire plugin allows us to include or exclude the tags in the plugin configuration:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<groups>UnitTest</groups>
</configuration>
</plugin>
If we now execute this plugin, it will execute all tests which are tagged as UnitTest. Similarly, we can exclude test cases under a tag name:
<excludedGroups>IntegrationTest</excludedGroups>
2.4. Filtering Tags with an IDE
IDEs now allow filtering the JUnit tests by tags. This way we can execute a specific set of tagged tests directly from our IDE.
IntelliJ allows such filtering through a custom Run/Debug Configuration:
π JUnit5 Tags in IntelliJAs shown in this image, we selected the Test Kind as tags and the tag to be executed in the Tag Expression.
JUnit 5 allows various Tag Expressions which can be used to filter the tags. For example, to run everything but the integration tests, we could use !IntegrationTest as the Tag Expression. Or for executing both UnitTest and IntegrationTest, we can use UnitTest | IntegrationTest.
Similarly, Eclipse also allows including or excluding tags in the JUnit Run/Debug configurations:
π JUnit5 Tags in Eclipse3. JUnit 4 Categories
3.1. Categorizing JUnit Tests
JUnit 4 allows us to execute a subset of JUnit tests by adding them into different categories. As a result, we can execute the test cases in a particular category while excluding other categories.
We can create as many categories by implementing marker interfaces where the name of the marker interface represents the name of the category. For our example, weβll implement two categories, UnitTest:
public interface UnitTest {
}
and IntegrationTest:
public interface IntegrationTest {
}
Now, we can categorize our JUnit by annotating it with Category annotation:
@Test
@Category(IntegrationTest.class)
public void testAddEmployeeUsingSimpelJdbcInsert() {
}
@Test
@Category(UnitTest.class)
public void givenNumberOfEmployeeWhenCountEmployeeThenCountMatch() {
}
In our example, we put the Category annotation on the test methods. Similarly, we can also add this annotation on the test class, thus adding all tests into one category.
3.2. Categories Runner
In order to execute JUnit tests in a category, we need to implement a test suite class:
@RunWith(Categories.class)
@IncludeCategory(UnitTest.class)
@SuiteClasses(EmployeeDAOCategoryIntegrationTest.class)
public class EmployeeDAOUnitTestSuite {
}
This test suite can be executed from an IDE and would execute all JUnit tests under the UnitTest category. Similarly, we can also exclude a category of tests in the suite:
@RunWith(Categories.class)
@ExcludeCategory(IntegrationTest.class)
@SuiteClasses(EmployeeDAOCategoryIntegrationTest.class)
public class EmployeeDAOUnitTestSuite {
}
3.3. Excluding or Including Categories in Maven
Finally, we can also include or exclude the categories of JUnit tests from the Maven build. Thus, we can execute different categories of JUnit tests in different Maven profiles.
Weβll use the Maven Surefire plugin for this:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<groups>com.baeldung.categories.UnitTest</groups>
</configuration>
</plugin>
And similarly we can exclude a category from the Maven build:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<excludedGroups>com.baeldung.categories.IntegrationTest</excludedGroups>
</configuration>
</plugin>
This is similar to the example we discussed in the previous section. The only difference is that we replaced the tag name with the fully qualified name of the Category implementation.
4. Filtering JUnit Tests with Maven Surefire Plugin
Both of the approaches weβve discussed have been implemented with the JUnit library. An implementation agnostic way of filtering test cases is by following a naming convention. For our example, weβll use UnitTest suffix for unit tests and IntegrationTest for integration tests.
Now weβll use the Maven Surefire Plugin for executing either the unit tests or the integrations tests:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<excludes>
**/*IntegrationTest.java
</excludes>
</configuration>
</plugin>
The excludes tag here filters all integration tests and executes only the unit tests. Such a configuration would save a considerable amount of build time.
Furthermore, we can execute the Surefire plugin within various Maven profiles with different exclusions or inclusions.
Although Surefire works well for filtering, it is recommended to use the Failsafe Plugin for executing integration tests in Maven.
5. Conclusion
In this article, we saw a way to tag and filter test cases with JUnit 5. We used the Tag annotation and also saw various ways for filtering the JUnit tests with a specific tag through the IDE or in the build process using Maven.
We also discussed some of the filtering mechanisms before JUnit 5.
