JUnit @Tag and filter tests
|In this quick Junit tutorial, we will discuss the usage of @Tag
annotation and how we can filter the tests using the Gradle test execution.
1. @Tag Annotation
We use @Tag
annotation to include or exclude the tests during the execution.
Note: We can use one or more tags on a method or on a class.
Some examples where tag filtering can be helpful are –
- Running fast and slow test separately. For example – we can run unit tests(and some other verifications) and integration tests in parallel in a pipeline as generally integration tests take much more time and hence can reduce the overall pipeline time
- If we have a system that deploys on multiple platforms and we have a different set of tests for each platform. Then we can use tagging and filtering to run only required tests for each platform.
- Mark tests to run on different stages of deployment. For example, if we have multiple levels of deployments like testing environment, pre-production environment, then we can use these tags to run them based on the server they are running in.
1.1 Syntax rules for Tags
There are some syntax rules to define the tags
- A tag must be a valid String i.e. neither
null
nor Blank - A trimmed (with no leading or trailing whitespace characters) tag must not
- contain whitespace
- contain ISO control characters
- contain any of the following reserved characters
,
comma(
left parenthesis)
right parenthesis&
ampersand|
vertical bar!
exclamation point
2. Filter with @Tag and Gradle
Let’s implement a test class with three different filters fast, slow, and tag-on-class.
@Tag("tag-on-class") class TagAnnotaionExampleTest { @Tag("slow") @Test void slowTest() {} @Tag("fast") @Test void fastTest() {} @Tag("fast") @Tag("slow") @Test void alwaysRunTest() {} @Test void testWithoutTag() {} }
Also, let’s update the buld.gradle.kts file and add some tasks for filtering the tests based on tags.
tasks.register<Test>("slow"){ useJUnitPlatform { includeTags("slow") } } tasks.register<Test>("fast"){ useJUnitPlatform { includeTags("fast") } } tasks.register<Test>("tag-on-class"){ useJUnitPlatform { includeTags("tag-on-class") } } tasks.register<Test>("exclude-fast"){ useJUnitPlatform { excludeTags("fast") } }
Now let’s have a look at the output of different commands one by one.
./gradlew slow
Task :app:slow TagAnnotaionExampleTest [ com.codingeek.TagAnnotaionExampleTest ] ✓ slowTest() ✓ alwaysRunTest()
./gradlew fast
Task :app:fast TagAnnotaionExampleTest [ com.codingeek.TagAnnotaionExampleTest ] ✓ alwaysRunTest() ✓ fastTest()
./gradlew tag-on-class
In this case, we have included the tag on a class that will run all the methods of that class automatically. If we want to skip some tests then we have to explicitly exclude the tag.
Task :app:tag-on-class TagAnnotaionExampleTest [ com.codingeek.TagAnnotaionExampleTest ] ✓ testWithoutTag() ✓ slowTest() ✓ alwaysRunTest() ✓ fastTest()
./gradlew exclude-fast –tests TagAnnotaionExampleTest
Task :app:tag-on-class Task :app:exclude-fast TagAnnotaionExampleTest [ com.codingeek.TagAnnotaionExampleTest ] ✓ testWithoutTag() ✓ slowTest()
3. Conclusion
In this article, we have discussed the usage of @Tag annotation, its syntax rules, what are the real life usages of @Tag annotation, and how we can use create and run new tasks in Gradle to include or exclude the tags.
Complete code samples are present on Github project.
An investment in knowledge always pays the best interest. I hope you like the tutorial. Do come back for more because learning paves way for a better understanding
Do not forget to share and Subscribe.
Happy coding!! ?