How to AND JUnit5 tags with Maven

Viewed 1124

Is there a way to run only the tests with each of the given tags? For example, can we run only the tests with tag1 AND tag2?

We are using Maven 3.6.2 with version 2.22.2 of Surefire and JUnit 5.5.2 to run tests against many application API endpoints. Each test has at least 3 tags specifying test type, application and method type. Some have more.

We are currently running our tests from the command line to give the tester control over each run:

mvn test -Dgroups=app1,fast

The problem we run into is that the above will run all the tests tagged with app1 OR fast. The result is many dozens of tests being run. The tester's goal is to run only the "fast" tests for "app1".

While it is possible to use excludedGroups, this does not help the tester until after the run. Additionally, we are adding tests and tags every day so what worked today may not work tomorrow.

One of our goals is enabling the specification of tags on the command line and not require the tester to edit the POM to run a different combination of tests. We would like to specify our test sets from the command line and not have to touch the POM between runs. Due to the growing list of test combinations, our POM would become too large to manage efficiently.

Is ANDing JUnit5 tags together even possible with Surefire?

2 Answers

In Maven Surefire/Maven Failsafe you can define groups as you already mentioned but you can define it for JUnit Jupiter (aka JUnit 5) as like this:

mvn test -Dgroups="app1&fast"

or

mvn test -Dgroups="app1|fast"

for more details take a look into the documentation.

BTW: I recommend to upgrade to the most recent versions of maven-surefire-plugin or maven-failsafe-plugin.

They way I've done it was setup interfaces. If there are sub groups I just make the interface extend the parent.

For your case it seems like you have app1 tag and some of those tests tagged fast. Create interface for app1 and another for fast that extends app1. In your tests you can add @Category(app1Fast.class)

When you call mvn test -Dgroups=tests.groups.app1Fast it will run just the fast tags. If you run mvn clean test -Dgroups=tests.groups.app1 it will run everything in app1.

Also, you can tell I created a package called groups to add my interfaces in.

Another also, the interface will be empty -

public interface app1 {}

public interface app1Fast extends app1{}

Sounds like you'll have multiple apps -- app1, app2, etc.

public interface app2{}
public interface app2Fast extends app2{}

Probably other ways, but this is simple enough.

call app1 to test everything in app1, or app1Fast for only the fast tests for app1. Same for app2.

Hope that helps.

Related