0% found this document useful (0 votes)
48 views21 pages

Introduction To Junit5 Tags

This document provides an introduction to tagging test methods in JUnit 5. It describes how to add one or multiple tags to test classes, nested test classes, and individual test methods using the @Tag annotation. It also discusses writing a custom annotation to make tagging tests easier.

Uploaded by

Gaurav Saxena
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
48 views21 pages

Introduction To Junit5 Tags

This document provides an introduction to tagging test methods in JUnit 5. It describes how to add one or multiple tags to test classes, nested test classes, and individual test methods using the @Tag annotation. It also discusses writing a custom annotation to make tagging tests easier.

Uploaded by

Gaurav Saxena
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

Introduction to JUnit 5 Tags

Petri Kainulainen
Table of Contents

About the Author. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Tagging Test Methods With JUnit 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Adding One Tag to Your Test Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Adding Multiple Tags to Your Test Methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Writing a Custom Annotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Introduction to Tag Expressions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Filtering Tests With Maven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Filtering Tests With Gradle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
About the Author

Petri Kainulainen is a Finnish software developer who is specialized in software


development with the Spring Framework. He got his first computer as a Christmas gift
when he was eight years old. A few months later he "wrote" his first computer program
by copying the code from the user’s manual of his Commodore 64.

At the time Petri had no idea what he was doing but the outcome of his work amazed
him. He wanted to learn more about this thing called programming. In a way, that
moment was the starting point of his career.

Petri has over two decades of experience in software development. During this time he
has participated in dozens of different software development projects as a software
architect. Currently he is working in a privately owned software company, where he
concentrates on adding value to customers and learning new things every day.

He also has a popular blog where he writes about Spring Framework and automated
testing. Petri has also published an online course which helps you to write better tests
JUnit 5.

By the way, Petri no longer practices copy and paste programming.

1
Introduction

This ebook provides a quick introduction to JUnit 5 tags. After you have read this
ebook, you:

• Understand how JUnit 5 tags work.


• Can add JUnit 5 tags to your test methods.
• Know how you can make your tests easier to write and maintain by using custom
annotations.
• Can select the invoked test cases by using tag expressions.
• Understand how you can filter tests with Maven and Gradle.

Let’s start by finding out how you can add tags to your test methods.

2
Tagging Test Methods With JUnit 5

JUnit 5 tags allow you to divide your test methods into different groups and configure
the groups whose tests are run when you run your tests. When you want to add a tag
to a test class or a test method, you have to:

1. Annotate your test class or test method with the @Tag annotation.
2. Configure the name of your tag by setting the value of the @Tag annotation’s value
attribute.

When you configure the name of your tag, you must use a non-null value that isn’t
blank. Also, when JUnit 5 validates the name of your tag, it removes the leading and
trailing whitespace characters from it. After this has been done, JUnit 5 ensures that
the remaining name doesn’t:

• Contain whitespace characters.


• Contain ISO controller characters.
• Contain any reserved characters.

If you need more information about the syntax rules concerning JUnit 5
tags, you should take a look at the JUnit 5 User Guide.
 Additional Reading

• The Javadoc of the @Tag annotation

When you annotate a test class with the @Tag annotation, Junit 5 has to decide which
test methods get the given tag. JUnit 5 finds these test methods by following these
steps:

First, JUnit 5 transforms the class hierarchy of your test class into a tree. The
annotated test class is the root node of the created tree and the nested test classes
which are enclosed by the annotated test class are added to the created tree as
nodes.

The following figures illustrate the structure of two imaginary trees:

3
Example 1: The @Tag Annotation Is Added to a Test Class

Example 2: The @Tag Annotation Is Added to a Nested Test Class

Second, JUnit 5 finds all paths from the root node (aka the annotated test class) to the
leaf nodes. A leaf node is either a "normal" test class or a nested test class which don’t
contain any nested test classes.

The following figure illustrates the paths found from the tree illustrated by the example
1:

4
Third, JUnit 5 iterates the found paths one by one and processes all test classes found
from the inspected path by following these steps:

1. Find the test methods of the inspected class.


2. Iterate the found test methods one by one.
3. If the test method doesn’t have the specified tag, add the tag to the inspected test
method.

Next, we will take look at some examples which demonstrate how you can add one tag
to your test methods.

5
Adding One Tag to Your Test Methods

When you want to add one tag to your test methods, you can use one of these three
options:

First, if you want to add a tag to all test methods found from your test class, you have
to annotate your test class with the @Tag annotation. For example, let’s assume that
you want to add the tag 'A' to all test methods found from your test class.

After you have made the required changes to your test class, it looks as follows:

import org.junit.jupiter.api.Tag;

@Tag("A")
class RootClassTagAExampleTest {
}

Second, if you want to add a tag to all test methods found from a nested test class,
you have to annotate your nested test class with the @Tag annotation. For example,
let’s assume that your test class has two nested test classes and you want that:

• The test methods found from the WhenTestHasTagA class have the tag 'A'.
• The test methods found from the WhenTestHasTagB class have the tag 'B'.

After you have the made required changes to your test class, it looks as follows:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Tag;

class NestedClassTagExampleTest {

@Nested
@DisplayName("When the test has the tag: A")
@Tag("A")
class WhenTestHasTagA {
}

@Nested
@DisplayName("When the test has the tag: B")
@Tag("B")
class WhenTestHasTagB {
}
}

6
Third, if you want to add a tag to one test method, you have to annotate your test
method with the @Tag annotation. For example, let’s assume that your test class has
two test methods and you want add different tags ('A' and 'B') to these test methods.

After you have made the required changes to your test class, its source code looks as
follows:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

class RootClassMethodTagExampleTest {

@Test
@DisplayName("Should have the tag: A")
@Tag("A")
void shouldHaveTagA() {
}

@Test
@DisplayName("Should have the tag: B")
@Tag("B")
void shouldHaveTagB() {
}
}

Let’s move on and find out how you can add multiple tags to your test methods.

7
Adding Multiple Tags to Your Test Methods

If you want to add multiple tags to your test methods, you can use one of these two
options:

First, because the @Tag annotation is a repeatable annotation, you can simple apply
multiple @Tag annotations to your test class, nested test class, or test method. For
example, let’s assume that you want to add the tags 'A' and 'B' to all test methods
found from your test class.

After you have made the required changes to your test class, its source code looks as
follows:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

@Tag("A")
@Tag("B")
class RootClassMultipleTagsExampleTest {
}

Second, you can annotate your test class, nested test class, or test method with the
@Tags annotation and configure the tags by setting the value of the @Tags annotation’s
value attribute. For example, let’s assume that you want to add the tags 'A' and 'B' to
all test methods found from your test class.

After you have made the required changes to your test class, its source code looks as
follows:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Tags;
import org.junit.jupiter.api.Test;

@Tags({
@Tag("A"),
@Tag("B")
})
class RootClassMultipleTagsExampleTest {
}

8
Additional Reading:
 • The Javadoc of the @Tags annotation

Next, you will find out how you can make your tests easier to write and maintain when
you are adding tags to your test methods.

9
Writing a Custom Annotation

When you add tags to your test methods, you must specify the names of your tags by
using string literals. Because it’s very like that you want to add the same tag to test
methods which are found from different test classes, you must write the same name
multiple times. This is a problem because:

• You have to remember the correct spelling of your tag’s name and double-check
that the name of your tag doesn’t contain any typos. This makes your tests hard to
write.
• If you want to change the name of your tag, you have to make that change to every
test class which contains the updated tag. This makes your tests hard to maintain.

It’s clear that you should remove duplicate tag names from your test suite. You can get
rid of duplicate tag names by writing a custom annotation which adds the required tag
to your test methods.

You can also declare constants which contain your tag names and use
these constants together with the @Tag annotation. However, I think that
 using custom annotations is a better choice because they make your
test code a bit easier to read.

Let’s assume that you want to write a custom annotation which adds the tag 'unitTest'
to your test methods. You can write this annotation by following these steps:

1. Create a new annotation class.


2. Ensure that you can annotate both test classes and test methods with your new
annotation.
3. Ensure that your annotation is recorded in the class file by the compiler and
retained by the VM at runtime.
4. Ensure that your custom annotation is part of the public contract of the annotated
element.
5. Ensure that you can add the tag 'unitTest' to your test methods by using your new
annotation.

After you have written your custom annotation, its source code looks as follows:

10
import org.junit.jupiter.api.Tag;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.TYPE, ElementType.METHOD })


@Retention(RetentionPolicy.RUNTIME)
@Documented
@Tag("unitTest")
public @interface UnitTest {
}

You can now add the tag 'unitTest' to your test methods by annotating your test
classes and test methods with the @UnitTest annotation. For example, let’s assume
that you want to add the tag 'unitTest' to all test methods found from your test class.

After you have made the required changes to your test class, its source code looks as
follows:

@UnitTest
class UnitTestAnnotationExampleTest {
}

As you can see, if you replace the @Tag annotation with a custom annotation, you will
make your life easier because:

• You don’t have to remember the correct spelling of your tag’s name and you cannot
make any typos when you add this tag to your test methods.
• If you want to change the name of your tag, you have to make that change to only
one place.

You can now divide your test methods into groups by using JUnit 5 tags. Let’s move
on and find out how can select the invoked test methods by using tag expressions.

This ebook consists of the free sample lessons of my JUnit 5 course. If


you want to learn how you can save time when you have to write tests
 with JUnit 5, you should take a look at my Introduction to JUnit 5
course.

11
Introduction to Tag Expressions

Tag expressions are boolean expressions which allow you to specify the test methods
which are run when you run your tests. When you specify tag expressions, you can
combine tag names with the following operators:

Operator Description Associativity


! not right
& and left
| or left

The previous table lists the operators in the descending order of


 precedence. Also, you can adjust the operator precedence by using
parentheses (aka round brackets).

Let’s take a look at some examples which demonstrate how you can use tag
expressions for selecting the invoked test methods.

First, if you want to run all tests which have the tag 'A', you have to use a tag
expression that looks as follows:

Second, if you want to run all tests which have the tag 'A' or the tag 'B', you have to use
a tag expression that looks as follows:

A | B

Third, if you want to run all tests which have the tag 'A' and the tag 'B', you have to use
a tag expression that looks as follows:

A & B

Fourth, if you want to run all tests which have the tag 'A' and don’t have the tag 'B', you
have to use a tag expression that looks as follows:

A & !B

12
Fifth, if you want to run all tests which have the tag 'unitTest' or the tag
'integrationTest' and have the tag 'A' or the tag 'B', you have to use a tag expression
that looks as follows:

(unitTest | integrationTest) & (A | B)

Additional Reading:
 • JUnit 5 User Guide: 4.6.2. Tag Expressions

Next, you will learn to filter tests with Maven.

13
Filtering Tests With Maven

When you are running your tests by using either the Maven Surefire or the Maven
Failsafe plugin and you want to configure the test methods which are run when you
run your tests, you can use these two configuration options:

• The groups configuration option allows you to configure the tag expression which
specifies the test methods which are run when you run your tests.
• The excludedGroups configuration option allows you to configure the tag
expression which specifies the test methods which aren’t run when you run your
tests.

Let’s take a look at some examples which demonstrate how you can use these
configuration options.

First, let’s assume that you want to run all tests which have the tag 'A'. After you have
made the required changes to the configuration of the Maven Surefire plugin, its
configuration looks as follows:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<groups>A</groups>
</configuration>
</plugin>

Second, let’s assume that you want to run all tests which have the tags 'A' and 'B'.
After you have made the required changes to the configuration of the Maven Surefire
plugin, its configuration looks as follows:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<groups>A &amp; B</groups>
</configuration>
</plugin>

14
If you want to use the ampersand character ('&') in an XML document, you must
use a CDATA section or use the entity &amp;.

Third, let’s assume that you want to run all tests which have the tag 'A' or the tag 'B'
and don’t have the tag 'integrationTest'. After you have made the required changes to
the configuration of the Maven Surefire plugin, its configuration looks as follows:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<groups>A | B</groups>
<excludedGroups>integrationTest</excludedGroups>
</configuration>
</plugin>

On the other hand, if you don’t want to use two different configuration options, you can
remove the excludedGroups configuration option and use a tag expression that
excludes test methods which have the tag 'integrationTest'. After you have made the
required changes to the configuration of the Maven Surefire plugin, its configuration
looks as follows:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<groups>(A | B) &amp; !integrationTest</groups>
</configuration>
</plugin>

Additional Reading:

 • Maven Surefire Plugin: Using JUnit 5 Platform – Filtering by Tags


• Maven Failsafe Plugin: Using JUnit 5 Platform – Filtering by Tags

Let’s move on and find out how you can filter tests with Gradle.

15
Filtering Tests With Gradle

When you are running your tests with Gradle and you want to configure the test
methods which are run when you run your tests, you have to change the configuration
of the `Test task which runs your tests. To be more specific, you can use these two
configuration options:

• The includeTags configuration option allows you to configure the tag expression
which specifies the test methods which are run when you run your tests.
• The excludeTags configuration option allows you to configure the tag expression
which specifies the test methods which aren’t run when you run your tests.

Let’s take a look at some examples which demonstrate how you can use these
configuration options.

First, let’s assume that you want to run all tests which have the tag 'A'. After you have
made the required changes to the configuration of the Test task, its configuration
looks as follows:

test {
useJUnitPlatform {
includeTags 'A'
}
}

Second, let’s assume that you want to run all tests which have the tags 'A' and 'B'.
After you have made the required changes to the configuration of the Test task, its
configuration looks as follows:

test {
useJUnitPlatform {
includeTags 'A & B'
}
}

Third, let’s assume that you want to run all tests which have the tag 'A' or the tag 'B'
and don’t have the tag 'integrationTest'. After you have made the required changes to
the configuration of the Test task, its configuration looks as follows:

16
test {
useJUnitPlatform {
includeTags 'A | B'
excludeTags 'integrationTest'
}
}

On the other hand, if you don’t want to use two different configuration options, you can
remove the excludeTags configuration option and use a tag expression that excludes
test methods which have the tag 'integrationTest'. After you have made the required
changes to the configuration of the Test task, its configuration looks as follows:

test {
useJUnitPlatform {
includeTags '(A | B) & !integrationTest'
}
}

Additional Reading:
 • Gradle User Manual: Testing in Java & JVM projects – Test Grouping

You can now add tags to your test methods and filter your test methods with Maven
and Gradle. Let’s summarize what you learned from this ebook.

17
Summary

This ebook has taught you that:

• JUnit 5 tags allow you to divide your test methods into different groups and
configure the groups whose tests are run when you run your tests.
• If you want to add one tag to your test methods, you have to annotate your test
class, nested test class, or test method with the @Tag annotation.
• If you want to add multiple tags to your test methods, you have to annotate your
test class, nested test class, or test method with the @Tags annotation or apply
multiple @Tag annotations to your test class, nested test class, or test method.
• Tag expressions are boolean expressions which allow you to specify the test
methods which are run when you run your tests. When you want to create a new tag
expression, you have to combine tag names with logical operators.
• If you are using Maven, you can include and exclude test methods by using the
groups and excludedGroups configuration options.
• If you are using Gradle, you can include and exclude test methods by using the
includeTags and excludeTags configuration options.

This ebook consists of the free sample lessons of my JUnit 5 course. If


you want to learn how you can save time when you have to write tests
 with JUnit 5, you should take a look at my Introduction to JUnit 5
course.

18

You might also like