Close

JUnit 5 - Selecting specific test classes for suites, Using @SelectClasses with @Suite

[Last Updated: Dec 19, 2025]

The @SelectClasses annotation allows you to explicitly select individual test classes to include in your test suite. This provides the most precise control over suite composition, enabling you to create custom test combinations without relying on package-based selection.

How @SelectClasses Works

When you use @SelectClasses, you specify exact class references:

  1. Provide class literals for each test class you want to include
  2. The Suite Engine loads only the specified classes
  3. Tests are executed in the order they appear in the annotation (typically)
  4. No package scanning or pattern matching occurs

Benefits of Class-Level Selection

  • Precision: Include exactly the classes you want, nothing more
  • Performance: No package scanning overhead
  • Flexibility: Combine classes from different packages
  • Control: Explicit declaration of test dependencies
  • Maintainability: Clear visibility of which tests are included

Use Cases

  • Critical Path Tests: Select only the most important test classes
  • Smoke Test Suite: Create a quick verification suite
  • Component Integration: Combine tests for specific component interactions
  • Regression Test Selection: Choose tests for recently changed code
  • Custom Test Combinations: Create suites for specific scenarios or stakeholders

Java source and doc

Definition of SelectClasses

Version: 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 SelectClasses {
     Class<?>[] value() default {}; 1
     @API(status = MAINTAINED, since = "1.13.3")
     String[] names() default {}; 2
 }
1One or more classes to select.
2One or more classes to select by their fully qualified names. (Since 1.10)

Example

In this example we have following test classes:

$ tree /a /f
\---com
\---logicbig
\---example
AnotherExcludedTest.java
CriticalLoginTest.java
EssentialPaymentTest.java
ExcludedTest.java
OrderValidationTest.java
SuiteSelectClassesExample.java

Test classes

package com.logicbig.example;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class CriticalLoginTest {

    @Test
    void testAdminLogin() {
        System.out.println("CriticalLoginTest - Admin login test (SELECTED)");
        assertTrue(true, "Admin should be able to login");
    }

    @Test
    void testUserLogin() {
        System.out.println("CriticalLoginTest - User login test");
        assertEquals("user", "user", "Username should match");
    }

    @Test
    void testLoginFailure() {
        System.out.println("CriticalLoginTest - Login failure test");
        assertFalse(false, "Invalid credentials should fail");
    }
}
package com.logicbig.example;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class EssentialPaymentTest {

    @Test
    void testCreditCardPayment() {
        System.out.println("EssentialPaymentTest - Credit card payment test (SELECTED)");
        assertTrue(true, "Credit card payment should process");
    }

    @Test
    void testPaymentAmountValidation() {
        System.out.println("EssentialPaymentTest - Payment amount validation");
        assertTrue(50.0 > 0, "Payment amount should be positive");
    }
}
package com.logicbig.example;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class OrderValidationTest {

    @Test
    void testOrderTotalCalculation() {
        System.out.println("OrderValidationTest - Order total calculation test (SELECTED)");
        double subtotal = 100.0;
        double tax = 8.0;
        double total = subtotal + tax;

        assertEquals(108.0, total, 0.01, "Order total should be calculated correctly");
    }

    @Test
    void testOrderItemValidation() {
        System.out.println("OrderValidationTest - Order item validation");
        assertNotNull("item123", "Order item should have an ID");
    }
}
package com.logicbig.example;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class ExcludedTest {

    @Test
    void testExcludedFunctionality() {
        System.out.println("testExcludedFunctionality");

    }
}
package com.logicbig.example;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class AnotherExcludedTest {

    @Test
    void testAdditionalExcludedFunctionality() {
        System.out.println("testAdditionalExcluded");

    }
}

Suite class

package com.logicbig.example;

import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
import org.junit.platform.suite.api.SuiteDisplayName;

@Suite
@SuiteDisplayName("Critical Business Functionality Suite")
@SelectClasses({
    CriticalLoginTest.class,       // Select critical login tests
    EssentialPaymentTest.class,    // Select essential payment tests
    OrderValidationTest.class      // Select order validation tests
    // Note: ExcludedTest and AnotherExcludedTest are NOT selected
})
public class SuiteSelectClassesExample {
    // Only the three explicitly selected classes will be executed
    // This provides precise control over suite composition
}

Output

$ mvn test -Dtest=SuiteSelectClassesExample
[INFO] Scanning for projects...
[INFO]
[INFO] -----< com.logicbig.example:junit-5-suite-select-classes-example >------
[INFO] Building junit-5-suite-select-classes-example 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ junit-5-suite-select-classes-example ---
[WARNING] Using platform encoding (UTF-8 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-select-classes-example\src\main\resources
[INFO]
[INFO] --- compiler:3.14.1:compile (default-compile) @ junit-5-suite-select-classes-example ---
[INFO] No sources to compile
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ junit-5-suite-select-classes-example ---
[WARNING] Using platform encoding (UTF-8 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-select-classes-example\src\test\resources
[INFO]
[INFO] --- compiler:3.14.1:testCompile (default-testCompile) @ junit-5-suite-select-classes-example ---
[INFO] Recompiling the module because of changed source code.
[INFO] Compiling 6 source files with javac [debug target 25] to target\test-classes
[INFO]
[INFO] --- surefire:3.5.4:test (default-test) @ junit-5-suite-select-classes-example ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
CriticalLoginTest - Login failure test
CriticalLoginTest - Admin login test (SELECTED)
CriticalLoginTest - User login test
[INFO] +--com.logicbig.example.CriticalLoginTest - 0.371 ss
[INFO] | +-- [OK] testLoginFailure - 0.131 ss
[INFO] | +-- [OK] testAdminLogin - 0.053 ss
[INFO] | '-- [OK] testUserLogin - 0.039 ss
EssentialPaymentTest - Payment amount validation
EssentialPaymentTest - Credit card payment test (SELECTED)
[INFO] +--com.logicbig.example.EssentialPaymentTest - 0.014 ss
[INFO] | +-- [OK] testPaymentAmountValidation - 0.002 ss
[INFO] | '-- [OK] testCreditCardPayment - 0.002 ss
OrderValidationTest - Order total calculation test (SELECTED)
OrderValidationTest - Order item validation
[INFO] +--com.logicbig.example.OrderValidationTest - 0.025 ss
[INFO] | +-- [OK] testOrderTotalCalculation - 0.005 ss
[INFO] | '-- [OK] testOrderItemValidation - 0.005 ss
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 7, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.485 s
[INFO] Finished at: 2025-12-19T16:14:33+08:00
[INFO] ------------------------------------------------------------------------

The above output verifies that the class-level selection suite operates precisely as configured, executing only the three explicitly specified test classes: CriticalLoginTest, EssentialPaymentTest, and OrderValidationTest. All seven test methods from these selected classes ran successfully, with no excluded test classes appearing in the results. This demonstrates that @SelectClasses provides fine-grained control over suite composition, allowing for targeted execution of specific critical business functionality tests while completely omitting unselected classes from the test run.

Example Project

Dependencies and Technologies Used:

  • junit-jupiter-engine 6.0.1 (Module "junit-jupiter-engine" of JUnit)
     Version Compatibility: 5.8.0 - 6.0.1Version List
    ×

    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

JUnit 5 - @SelectClasses Example Select All Download
  • junit-5-suite-select-classes-example
    • src
      • test
        • java
          • com
            • logicbig
              • example
                • SuiteSelectClassesExample.java

    See Also