Skip to content
Chapter 11 · JUnit 5 & Mockito

Tagging and Filtering ​

Chapter 10 let a test skip itself. Tags choose from the outside which tests to run.

Tags categorize tests so you can run or skip a selection of them.

java
class PaymentTaggingTest {

    @Test
    @Tag("card")
    void validateCardScenario1() {
        System.out.println("inside Card testcase");
    }

    @Test
    @Tag("bank")
    void validateBankScenario1() {
        System.out.println("inside Bank testcase");
    }
}

With a hundred payment tests tagged this way, you can run only the bank ones.

Rules for tag names ​

  1. Not null or empty. @Tag(" ") is invalid.
  2. No whitespace after stripping. JUnit first strips leading and trailing whitespace, so @Tag(" cardPayment ") is valid (it becomes cardPayment); @Tag("bank payment") is not.
  3. No reserved characters: , ( ) & | !, because they are the operators of tag expressions (below).

An invalid tag does not break the test; it is ignored with a warning:

text
[WARNING] Invalid tag syntax in @Tag("bank payment") declaration on method '...invalid()'. Tag will be ignored.

Multiple tags and class tags ​

java
@Tag("slow")                        // class level: applies to every test in the class
class PaymentTaggingTest {

    @Test
    @Tag("card")
    @Tag("visa")
    void validateCardScenario1() { ... }   // tags: card, visa, slow

    @Test
    @Tag("bank")
    void validateBankScenario1() { ... }   // tags: bank, slow
}

Tag expressions ​

Selections are written as boolean expressions over tag names, with the operators & (and), | (or), ! (not) and parentheses:

ExpressionSelects
card & visatests with both card and visa
card | visatests with either
!visatests without visa
bank | ((card & visa) & !slow)bank tests, or tests that are card and visa but not slow

With the class above, the last expression selects only validateBankScenario1: the card/visa test also carries the class-level slow tag.

Running a selection ​

IntelliJ ​

Run → Edit Configurations, choose the JUnit configuration, set Test kind to Tags, and enter a tag expression. IntelliJ passes it to the JUnit Launcher, and only matching tests run.

Maven ​

mvn test runs the test phase, executed by the Surefire plugin (the Maven lifecycle is covered in the Spring Boot series). Its groups setting takes a tag expression:

xml
<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.2.5</version>
            <configuration>
                <groups>bank | card</groups>
            </configuration>
        </plugin>
    </plugins>
</build>

mvn test now runs only bank or card tests. (excludedGroups does the opposite.)

Hard-coding the expression in pom.xml is inflexible: sometimes you want everything, sometimes another selection. Surefire reads the groups property from the command line, so leave pom.xml alone and choose at run time:

bash
mvn test -Dgroups="bank | card"
mvn test                            # no filter: runs all tests

(-D sets a property.) If you want the setting switched on only deliberately, you can put it in a Maven profile and activate it with -P:

xml
<profiles>
    <profile>
        <id>tagTest</id>
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <groups>${groups}</groups>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
bash
mvn test -PtagTest -Dgroups="bank | card"

A profile is like a switch: active with -P<id>, ignored otherwise.

Test suites (next chapter) are another way to group and run tests together.

Next: Chapter 12 covers test suites, the other way to group tests and run a group together, and compares the two.

Check yourself ​

  1. What are tags for?
  2. Which of these are valid: @Tag(" "), @Tag(" cardPayment "), @Tag("bank payment"), @Tag("card&visa")? What happens to an invalid one?
  3. Why can a tag not contain & or |?
  4. A class is tagged slow and a method card and visa. Which tags does the method have?
  5. Write expressions for: tests with both card and visa; tests without visa.
  6. How do you choose the tag expression for mvn test at run time?
Answers
  1. To categorize tests so a selection can be run or skipped.
  2. Only " cardPayment " (stripped to cardPayment). Invalid tags are ignored with a warning; the test still runs.
  3. They are operators in tag expressions.
  4. card, visa and slow.
  5. card & visa; !visa.
  6. mvn test -Dgroups="<expression>" (Surefire's groups property), optionally inside a profile.