Automated system integration tests are useful for testing user acceptance criteria as a whole. In addition, we also use the tests to verify environment set up such as file, database and external web service access. We run these tests on production systems to verify deployment. Some of the automated tests in our integration test suites are not safe to be run on production. This blog posts explain how I use Junit 5 @Tag annotation and the Failsafe plugin to separate system integration tests into all enviroment and non production only.
Junit 5 allows test classes and methods to be tagged via the @Tag annotation. The tests can be used to filter test discovery and execution. I used the tag NonProductionOnly for test classes that should not be run on a production environment.
@Tag("NonProductionOnly")
public class PlaceOrderTestsIT {
....
}
Junit tests that are safe to be run on all environments are not annotated.
The Failsafe Plugin is designed to run integration tests while the Surefire Plugin is designed to run unit tests. It decouples failing the build if there are test failures from actually running integration tests. For unit tests to be handled by the Failsafe plugin, end the class name with IT. To filter executions with Junit 5 @Tag annotations, the plugin can be configured in the project’s pom.xml.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<excludedGroups>${failsure.excludedGroups}</excludedGroups>
</configuration>
</plugin>
</plugins>
</build>
This configures the plugin to exclude groups defined in the pom property ${failsure.excludedGroups}. We set up the property using maven profiles. The tag NothingToExclude does not correspond to any @Tag in the test suite. It is needed in the pom because the property cannot be left empty.
<profiles>
<profile>
<id>uat</id>
<properties>
<failsure.excludedGroups>NothingToExclude</failsure.excludedGroups>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<failsure.excludedGroups>NonProductionOnly</failsure.excludedGroups>
</properties>
</profile>
</profiles>
The profiles are passed in from Jenkins configuration for the different environments.