In this article we will see that what is Junit 5 conditional test execution, and walk through what are the different Conditions that Jupiter api supports with several examples.
JUnit Jupiter api supports several annotation-based conditions in the
org.junit.jupiter.api.condition
package that allow developers to enable or disable containers and tests declaratively. The simplest example of such a condition is the built-inDisabledCondition
which supports the@Disabled
annotation.
1. Junit 5 conditional test execution
Following are the several Conditions Junit 5 Jupiter api supports to enable or disable test cases.
- Operating System Conditions via
@EnabledOnOs
and@DisabledOnOs
annotations. - Java Runtime Environment Conditions via
@EnabledOnJre
,@DisabledOnJre
,@EnabledForJreRange
and@DisabledForJreRange
annotations. - System Property Conditions via the
@EnabledIfSystemProperty
and@DisabledIfSystemProperty
annotations. - Environment Variable Conditions via
@EnabledIfEnvironmentVariable
and@DisabledIfEnvironmentVariable
annotations. - Script Based Conditions via the
@EnabledIf
or@DisabledIf
annotation. - Create Custom Condition by using the
ExecutionCondition
extension API.1.
1. Operating System Conditions
1.1 Enabled or disabled tests based on a particular operating system via @EnabledOnOs
and @DisabledOnOs
annotations.
public class OperatingSystemConditionalTest { @Test @EnabledOnOs(OS.MAC) void runOnlyOnMacOs() { System.out.println("Run the batch job only on MAC OS"); } @Test @EnabledOnOs({ OS.LINUX, OS.MAC }) void runOnlyOnLinuxOrMac() { System.out.println("Run the batch job only on LINUX or MAC OS"); } @Test @DisabledOnOs(OS.WINDOWS) void notRunOnWindows() { System.out.println("Not run the batch job on WINDOWS OS"); } @Test @EnabledOnOs({ OS.WINDOWS }) void runOnlyOnWindows() { System.out.println("Run the batch job only on WINDOWS OS"); } @Test @DisabledOnOs({OS.AIX, OS.LINUX, OS.SOLARIS}) void notRunOnAIXorLinuxOrSolaris() { System.out.println("Not run the batch job on AIX or LINUX or SOLARIS"); } }
2. Java Runtime Environment Conditions
2.1 Enabled or disabled tests based on a particular Java Runtime Environment (JRE) via @EnabledOnJre
and @DisabledOnJre
annotations.
2.2. Enabled or disabled tests based on a particular particular range of versions of the JRE via @EnabledForJreRange
and @DisabledForJreRange
annotations ( Introduced in Junit 5.6.0 ).
public class JavaRuntimeEnvironmentConditionalTest { @Test @EnabledOnJre(JRE.JAVA_8) void runOnlyOnJava8() { System.out.println("Run the compatibility test only on JRE 8"); } @Test @EnabledOnJre({JRE.JAVA_13, JRE.JAVA_14}) void runOnlyOnJava13OrJava14() { System.out.println("Run the compatibility test only on JRE 13 and JRE 14"); } @Test @DisabledOnJre(JRE.JAVA_13) void notRunOnJava13() { System.out.println("not run the compatibility test on JRE 13"); } @Test @EnabledOnJre(JRE.JAVA_11) void runOnlyOnJava11() { System.out.println("Run the compatibility test only on JRE 11"); } @Test @DisabledOnJre({JRE.JAVA_10, JRE.JAVA_11}) void notRunOnJava10andJava11() { System.out.println("not Run the compatibility test on JRE 10 and JRE 11"); } }
3. System Property Conditions
3.1 Enabled or disabled tests based on the value of the named
from the JVM system property via @EnabledIfSystemProperty
and @DisabledIfSystemProperty
annotations.
public class SystemPropertiesConditionalTest { @Disabled @Test void printSystemProperties() { //remove @Disabled to see System properties System.getProperties().forEach((key, value) -> System.out.println(key+" - "+value)); } @Test @EnabledIfSystemProperty(named = "java.vm.vendor", matches = "Oracle.*") void runOnlyOnOracleJDK() { System.out.println("Run this only on Oracle JDK"); } @Test @EnabledIfSystemProperty(named = "os.arch", matches = ".*32.*") void runOnlyOn32bitOS() { System.out.println("Run this on only on 32 bit OS"); } @Test @DisabledIfSystemProperty(named = "os.version", matches = ".*10.*") void notRunOnlyOnWindows10() { System.out.println("not run this only on windows 10 version"); } @Test @EnabledIfSystemProperty(named = "os.version", matches = ".*10.*") void runOnlyOnWindows10() { System.out.println("Run this only on WINDOWS OS 10 version"); } }
4. Environment Variable Conditions
4.1. Enabled or disabled tests based on the value of the named
attribute via @EnabledIfEnvironmentVariable
and @DisabledIfEnvironmentVariable
annotations.
public class EnvironmentVariableConditionalTest { @Disabled @Test void printSystemProperties() { // Remove @Disabled to see environment properties System.getenv().forEach((key, value) -> System.out.println(key+" - "+value)); } @Test @EnabledIfEnvironmentVariable(named = "COMPUTERNAME", matches = "sysname") void runOnlyOnPerticularMachine() { System.out.println("Run this only on perticular server"); } @Test @DisabledIfEnvironmentVariable(named = "PROCESSOR_ARCHITECTURE", matches = ".*32.*") void noRrunOn32bitOS() { System.out.println("Not run this on 32 bit OS"); } @Test @EnabledIfEnvironmentVariable(named = "USERNAME", matches = "username") void runOnlyForPerticularUser() { System.out.println("run this only for perticular user in system"); } }
5. Script Based Conditions (Deprecated since 5.5)
5.1. @EnabledIf
or @DisabledIf
annotations are used to Enable or Disable test cases based on script, they are deprecated in 5.5 version. But if you find yourself script-based condition required for your project, you can create your own condition to achieve that by using ExecutionCondition extension.
public class ScriptBasedConditionalTest { @Disabled @DisplayName("Java Nashorn script Test") @Test void nashornTest(TestInfo testinfo) { ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); try { // remove @Disabled to Demonstrating how nashorn script works Object result1 = engine.eval("2 * 3 == 6"); System.out.println("(2 * 3 == 6) => "+result1); Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE); bindings.put("systemProperty", System.getProperties()); bindings.put("junitDisplayName", testinfo.getDisplayName()); bindings.put("junitTags", testinfo.getTags()); engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE); System.out.println("systemProperty.get('os.arch')) => "+engine.eval("systemProperty.get('os.arch')")); System.out.println("junitDisplayName => "+engine.eval("junitDisplayName")); System.out.println("junitTags => "+engine.eval("junitTags")); } catch (Exception e) { e.printStackTrace(); } } // Static JavaScript expression. @Test @EnabledIf("2 * 3 == 6") void runOnlyIfExpressionValueTrue() { System.out.println("(2 * 3 == 6) => true"); } // Regular expression testing bound system property. @Test @DisabledIf("/32/.test(systemProperty.get('os.arch'))") void notRunOn32bitOS() { System.out.println("Not run this on 32 bit OS"); } @Test @EnabledIf("'admin' == systemEnvironment.get('USERNAME')") void runOnlyForSpecificUser() { System.out.println("Run this only for specific user"); } // Multi-line script, can give custom engine name and custom reason. @Test @EnabledIf(value = { "load('classpath:script/myScript.js')", "", "myfunction(10) == true" }, engine = "javascript", reason = "On {annotation}, with script: {script}, result is: {result}\"") void runOnlyOnlyIfValueIsEven() { System.out.println("Run this only for Even numbers"); } }
6. Create Junit 5 Custom Condition
We can create a custom condition in two ways in Junit 5.
- Create custom annotation by using combination of built-in annotations.
- Create your own custom annotation be using implementing ExecutionCondition extension.
6.1. Create custom condition annotation
6.1.1. Following code shows you how to create a custom annotation in Junit 5.
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Test @EnabledOnOs({ OS.WINDOWS }) @EnabledIfSystemProperty(named = "os.version", matches = ".*10.*") @EnabledIfEnvironmentVariable(named = "PROCESSOR_ARCHITECTURE", matches = ".*64.*") public @interface RunOnlyOn64bitWindows10 { }
6.1.2. Usage of custom created annotation
public class CustomConditionalTest { @RunOnlyOn64bitWindows10 void runOnlyOn64bitWindows10() { System.out.println("Run only this on 64 bit Windows 10 System."); } }
6.2. Create custom condition annotation by implementing ExecutionCondition
6.2.1. Following code shows you how to create your own conditional annotation by using ExecutionCondition
extension.
public class MyDisabledIfConditionExtension implements ExecutionCondition { private static final ConditionEvaluationResult ENABLED = ConditionEvaluationResult .enabled("@MyCustomDisabledIf is not present"); /** * @MyCustomDisabledIf - your own annotation */ @Override public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { Optional<AnnotatedElement> element = context.getElement(); Optional<MyCustomDisabledIf> disabled = findAnnotation(element, MyCustomDisabledIf.class); ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); boolean result = false; // result = write logic for disable test using your script engine. if (result) return ConditionEvaluationResult.disabled("@MyDisabledIf is present with valid condition"); return ENABLED; } }
6.2.2. Example using @MyCustomDisabledIf
public class MyCustomConditionalTest { @MyCustomDisabledIf("'sysUsername' == systemEnvironment.get('USERNAME')") void notRunForSpecificUser() { System.out.println("not run this for specific user"); } @MyCustomEnabledIf("/64/.test(systemProperty.get('os.arch'))") void runOnlyOn64bitMachine() { System.out.println("Run this only 64bit System"); } }
Conclusion
In this article we have seen that what is Junit 5 conditional test execution, and walked through what are the different Conditions that Jupiter api supports with several examples.
You also might be interested in following examples :
- Junit 5 Dynamic Tests and @TestFactory annotation.
- Junit 5 tags and filter test cases for execution.
- Junit 5 Timeout tests, fail tests if not completed within time.
- Junit 5 Repeated tests and display Repetition info.
- Junit 5 parameterized tests with different argument sources.
- Junit 5 Disable tests using @Disabled annotation
ExecutionCondition example you gave does not a any sense. You define a disable but where are you using it. Where is your MyCustomDisabledIf defined and how you use it on the test.
Hi Pavan, Thanks for the comment.
In this example we try to provide guidelines how to implement your own ExecutionCondition. You can checkout complete examples in our github
ExecutionCondition
Custom ExecutionCondition Example