The JUnit Platform Suite Engine allows you to combine multiple filters to create sophisticated test selection strategies. By using annotations like @IncludeTags and@ExcludeTags, you can create highly targeted test suites for specific scenarios, environments, or testing purposes.
Filter Combination Strategy
When combining multiple filters, the Suite Engine applies them in a logical sequence:
- Package Selection: First, select packages using
@SelectPackages or classes using @SelectClasses
- Package Filtering: Apply
@IncludePackages and @ExcludePackages
- Class Name Filtering: Apply
@IncludeClassNamePatterns and @ExcludeClassNamePatterns
- Tag Filtering: Apply
@IncludeTags and @ExcludeTags
Tag-Based Filtering
Tags provide a flexible way to categorize tests:
@IncludeTags: Only include tests with specified tags
@ExcludeTags: Exclude tests with specified tags
- Tags can represent test types, features, priorities, or environments
Use Cases for Combined Filters
- Environment-Specific Testing: Run only tests tagged for current environment
- Feature Testing: Test specific features across multiple packages
- Quality Gates: Create suites for different quality levels
- Selective Regression Testing: Target tests for changed functionality
Java source and doc
Definition of IncludeTagsVersion: 6.0.0 package org.junit.platform.suite.api;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
@Documented
@API(status = MAINTAINED, since = "1.0")
public @interface IncludeTags {
String[] value(); 1
}
Definition of ExcludeTagsVersion: 6.0.0 package org.junit.platform.suite.api;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
@Documented
@API(status = MAINTAINED, since = "1.0")
public @interface ExcludeTags {
String[] value(); 1
}
Example
In this example we have following classes:
$ tree /a /f Folder PATH listing for volume Joe Projects Volume serial number is D064-5C43 D:. \---com \---logicbig \---example CriticalUserTest.java ExcludedLegacyTest.java IntegrationPaymentTest.java PerformanceUserTest.java SlowOrderTest.java SuiteCombiningFiltersExample.java
Test Classes
package com.logicbig.example;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@Tag("critical")
@Tag("user")
public class CriticalUserTest {
@Test
void testCriticalUserLogin() {
System.out.println("CriticalUserTest - Critical user login test");
assertTrue(true, "Critical user should be able to login");
}
@Test
@Tag("security")
void testUserSecurity() {
System.out.println("CriticalUserTest - User security test");
assertEquals("secure", "secure", "User security should be enforced");
}
}
package com.logicbig.example;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@Tag("user")
@Tag("slow") // This tag causes exclusion
public class PerformanceUserTest {
@Test
void testUserPerformance() {
System.out.println("PerformanceUserTest - User performance test");
}
}
package com.logicbig.example;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@Tag("payment")
@Tag("integration") // This tag causes exclusion
public class IntegrationPaymentTest {
@Test
void testPaymentIntegration() {
System.out.println("IntegrationPaymentTest - Payment integration test");
}
}
package com.logicbig.example;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@Tag("order")
@Tag("slow")
public class SlowOrderTest {
@Test
void testSlowOrderProcessing() {
System.out.println("SlowOrderTest - Slow order processing test");
}
}
package com.logicbig.example;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@Tag("critical")
public class ExcludedLegacyTest {
@Test
void testLegacyFunctionality() {
System.out.println("ExcludedLegacyTest - Legacy functionality test");
}
}
package com.logicbig.example;
import org.junit.platform.suite.api.*;
@Suite
@SuiteDisplayName("Comprehensive Filtered Test Suite")
@SelectPackages("com.logicbig.example") // Select all packages
// Package filtering
@IncludePackages({
"com.logicbig.example"
})
// Class name pattern filtering
@IncludeClassNamePatterns(".*Test$") // Only include classes ending with "Test"
@ExcludeClassNamePatterns(".*Legacy.*") // Exclude classes containing "Legacy"
// Tag filtering
@IncludeTags({
"critical", // Include tests tagged as critical
"user", // Include tests tagged as user-related
"payment" // Include tests tagged as payment-related
})
@ExcludeTags({
"slow", // Exclude slow tests
"integration" // Exclude integration tests
})
// Engine filtering (optional - commented out as we only use JUnit Jupiter)
// @IncludeEngines("junit-jupiter") // Only use JUnit Jupiter engine
// @ExcludeEngines("junit-vintage") // Exclude JUnit 4 engine
public class SuiteCombiningFiltersExample {
// This suite combines multiple filters:
// 1. Only classes ending with "Test"
// 2. Excluding classes with "Legacy" in name
// 3. Including tests tagged "critical", "user", or "payment"
// 4. Excluding tests tagged "slow" or "integration"
}
Output$ mvn test -Dtest=SuiteCombiningFiltersExample [INFO] Scanning for projects... [INFO] [INFO] ----< com.logicbig.example:junit-5-suite-combining-filters-example >---- [INFO] Building junit-5-suite-combining-filters-example 1.0-SNAPSHOT [INFO] from pom.xml [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- resources:3.3.1:resources (default-resources) @ junit-5-suite-combining-filters-example --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:\example-projects\junit-5\junit-5-suite-engine\junit-5-suite-combining-filters-example\src\main\resources [INFO] [INFO] --- compiler:3.11.0:compile (default-compile) @ junit-5-suite-combining-filters-example --- [INFO] No sources to compile [INFO] [INFO] --- resources:3.3.1:testResources (default-testResources) @ junit-5-suite-combining-filters-example --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:\example-projects\junit-5\junit-5-suite-engine\junit-5-suite-combining-filters-example\src\test\resources [INFO] [INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ junit-5-suite-combining-filters-example --- [INFO] Changes detected - recompiling the module! :source [WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent! [INFO] Compiling 6 source files with javac [debug target 17] to target\test-classes [INFO] [INFO] --- surefire:3.5.0:test (default-test) @ junit-5-suite-combining-filters-example --- [INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- CriticalUserTest - Critical user login test CriticalUserTest - User security test [INFO] +--Comprehensive Filtered Test Suite CriticalUserTest - 0.065 ss [INFO] | +-- [OK] testCriticalUserLogin - 0.039 ss [INFO] | '-- [OK] testUserSecurity - 0.008 ss [INFO] [INFO] Results: [INFO] [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 4.221 s [INFO] Finished at: 2025-12-19T11:52:25+08:00 [INFO] ------------------------------------------------------------------------
The test output demonstrates that the comprehensive filtered suite successfully applies multiple filtering criteria in conjunction, resulting in the execution of only CriticalUserTest with its two tagged test methods. This precise outcome confirms that all filters—package inclusion, class name pattern matching (including .*Test$ and excluding .*Legacy.*), and tag-based selection (including critical/user/payment tags while excluding slow/integration)—work correctly to create a highly targeted test suite that isolates specific critical business functionality while systematically excluding unwanted test categories.
Example ProjectDependencies and Technologies Used: - junit-jupiter-engine 6.0.1 (Module "junit-jupiter-engine" of JUnit)
Version Compatibility: 5.8.0 - 6.0.1 Version compatibilities of junit-jupiter-engine with this example:
- 5.8.0
- 5.8.1
- 5.8.2
- 5.9.0
- 5.9.1
- 5.9.2
- 5.9.3
- 5.10.0
- 5.10.1
- 5.10.2
- 5.10.3
- 5.10.4
- 5.10.5
- 5.11.0
- 5.11.1
- 5.11.2
- 5.11.3
- 5.11.4
- 5.12.0
- 5.12.1
- 5.12.2
- 5.13.0
- 5.13.1
- 5.13.2
- 5.13.3
- 5.13.4
- 5.14.0
- 5.14.1
- 6.0.0
- 6.0.1
Versions in green have been tested.
- junit-platform-suite-engine 6.0.1 (Module "junit-platform-suite-engine" of JUnit)
- JDK 25
- Maven 3.9.11
|