Is your test application having both JUnit 4 + Junit 5 tests? and you wants to create JUnit 4 + JUnint 5 test suites and run both type of tests at a time? The JUnitPlatform runner is a JUnit 4 based Runner
which enables you to run any test whether it’s from a Junit 5 or Junit 4. In this guide you will see how to create test suites for both Junit 5 and Junit 4 test cases and execute them using JUnitPlatform runner in several ways.
Annotating a class with @RunWith(JUnitPlatform.class)
allows you to run Junit Platform tests on Junit 4 environment. To create test suites, JUnit 5 provides two annotations @SelectPackages and @SelectClasses. Let’s have look into following examples to create test suites.
1. Project Structure for Test suites and test classes
Following is the project structure and created JUnit 5 + JUnit 4 test cases and test suites with in it. You can notice two different packages payment and registration and they are having couple of test classes.
2. Maven dependencies for Junit 5 and Junit 4 models
Include junit-jupiter-engine
, junit-platform-runner
, junit-vintage-engine
in maven pom.xml
.
<dependencies> <!-- Jupiter API for writing Junit 5 tests --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>${junit.jupiter.version}</version> <scope>test</scope> </dependency> <!-- Runner to execute tests on the JUnit Platform in a JUnit 4 --> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-runner</artifactId> <version>${junit.platform.version}</version> </dependency> <!--JUnit Vintage Engine to run JUnit 4 Tests --> <dependency> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> <version>${junit.jupiter.version}</version> </dependency> </dependencies>
3. Junit 5 + Junit 4 Test Classes
3.1. Following is the a simple test class, all the tests within this class created using Junit 4 @org.junit.Test
annotation under “..payment” package.
public class Junit4_Surcharge_Test { // Junit 4 test case @org.junit.Test public void surcharge_merchant_test() { // ..currentThread().getName() - just to print thread name which is running current test System.out.println("surcharge_merchant_test(): " + Thread.currentThread().getName()); } // Junit 4 test case @org.junit.Test public void surcharge_byCountry_test() { System.out.println("surcharge_byCountry_test(): " + Thread.currentThread().getName()); } // Junit 4 test case @org.junit.Test public void surcharge_formula_test() { System.out.println("surcharge_formula_test(): " + Thread.currentThread().getName()); } }
3.2. Following is a simple test class, all the tests created within this class using Junit 5 @org.junit.jupiter.api.Test
annotation under “..payment” package.
@Tag("regression") public class Junit5_Payment_Test { @Tag("acceptance") @Tag("baseline") @org.junit.jupiter.api.Test // Junit 5 test void payment_success_test() { System.out.println("payment_success_test(): " + Thread.currentThread().getName()); } @Tag("acceptance") @org.junit.jupiter.api.Test // Junit 5 test void payment_decline_test() { System.out.println("payment_decline_test(): " + Thread.currentThread().getName()); } @Tag("security") @org.junit.jupiter.api.Test // Junit 5 test void invalid_country_test() { System.out.println("invalid_country_test(): " + Thread.currentThread().getName()); } }
3.3. Following are the simple JUnit 5 tests created under “..registration” package.
public class Junit5_Registration_Test { @Test void registration_Success_Test() { System.out.println("registration_Success_Test(): " + Thread.currentThread().getName()); } @Test void registration_Fail_On_DocCheck_Test() { System.out.println("registration_Fail_On_DocCheck_Test(): " + Thread.currentThread().getName()); } }
public class Junit5_SDD_Test { @Test void simpl_dueDeligence_pass_Test() { System.out.println("simpl_dueDeligence_pass_Test(): " + Thread.currentThread().getName()); } @Test void simpl_dueDeligence_fail_Test() { System.out.println("simpl_dueDeligence_fail_Test(): " + Thread.currentThread().getName()); } }
4. Create Test suites and run with JUnitPlatform runner
4.1. Create Test suite with @IncludePackages
Following example demonstrates how to create test suite for Junit 5 + Junit 4 tests and running tests with in “..payment” package.
Note that surcharge tests are created in JUnit 4 model and payment tests are created in JUnit 5 model.
@RunWith(JUnitPlatform.class) @SuiteDisplayName("Run Junit 5 tests in Junit 4") @SelectPackages("com.javabydeveloper.test") @IncludePackages("com.javabydeveloper.test.payment") public class IncludePackages_TestSuite_Test { }
Run the above test suite : following is output
invalid_country_test(): main payment_decline_test(): main payment_success_test(): main surcharge_formula_test(): main surcharge_byCountry_test(): main surcharge_merchant_test(): main
In following image notice that, tests started by two different child runners, Junit Jupiter for JUnit 5 tests and JUnit Vintage for JUnit 4 tests.
4.2. Create test Suite with @SelectPackages
Following example demonstrates how to create test suite with @SelectPackages
and with multiple packages.
@RunWith(JUnitPlatform.class) @SuiteDisplayName("Run Junit 5 tests in Junit 4") @SelectPackages({ "com.javabydeveloper.test.payment", "com.javabydeveloper.test.registration"}) public class SelectPakages_TestSuite_Test { }
Run the above test suite : following is output
invalid_country_test(): main payment_decline_test(): main payment_success_test(): main simpl_dueDeligence_fail_Test(): main simpl_dueDeligence_pass_Test(): main registration_Fail_On_DocCheck_Test(): main registration_Success_Test(): main surcharge_formula_test(): main surcharge_byCountry_test(): main surcharge_merchant_test(): main
4.3. Create test Suite with @IncludeClassNamePatterns
Following example demonstrates how to create test suite with @IncludeClassNamePatterns
.
@RunWith(JUnitPlatform.class) @SelectPackages("com.javabydeveloper.test.payment") @IncludeClassNamePatterns("^.*Surcharge.*") // should match test calss, not method public class IncludeClassNamePattern_TestSuite_Test { }
Run the above test suite : following is output
surcharge_formula_test(): main surcharge_byCountry_test(): main surcharge_merchant_test(): main
4.4. Create test Suite with @ExcludeClassNamePatterns
Following example demonstrates how to create test suite with @ExcludeClassNamePatterns
.
@RunWith(JUnitPlatform.class) @SelectPackages("com.javabydeveloper.test.payment") @ExcludeClassNamePatterns("^.*Surcharge.*") // should match test calss, not method public class ExcludeClassNamePattern_TestSuite_Test { }
Run the above test suite : following is output
invalid_country_test(): main payment_decline_test(): main payment_success_test(): main
4.5. Create test Suite with @ExcludePackages
Following example demonstrates how to create test suite with @ExcludePackages
.
@RunWith(JUnitPlatform.class) @SelectPackages("com.javabydeveloper.test") @ExcludePackages("com.javabydeveloper.test.payment") public class ExcludePackages_TestSuite_Test { }
Run the above test suite : following is output
simpl_dueDeligence_fail_Test(): main simpl_dueDeligence_pass_Test(): main registration_Fail_On_DocCheck_Test(): main registration_Success_Test(): main
4.6. Create test Suite with @IncludeTags
Following example demonstrates how to create test suite with @IncludeTags
.
@RunWith(JUnitPlatform.class) @SelectPackages("com.javabydeveloper.test.payment") @IncludeTags("baseline|security") public class IncludeTags_TestSuite_Test { }
Run the above test suite : following is output
invalid_country_test(): main payment_success_test(): main
4.7. Create test Suite with @ExcludeTags
Following example demonstrates how to create test suite with @ExcludeTags
.
@RunWith(JUnitPlatform.class) @SelectPackages("com.javabydeveloper.test.payment") @ExcludeTags("acceptance&baseline") public class ExcludeTags_TestSuite_Test { }
Run the above test suite : following is output
invalid_country_test(): main payment_decline_test(): main surcharge_formula_test(): main surcharge_byCountry_test(): main surcharge_merchant_test(): main
5. An experimental run parallel tests with JUnitPlatform runner
I would like to run both JUnit 5 and JUnit 4 tests parallel with JUnitPlatform, I did an experimental run for the parallel tests execution> To run tests parallel you need to include configuration parameter junit.jupiter.execution.parallel.enabled=true
in junit-platform.properties
under src\test\resources
. Following configuration is to run all the test classes and test methods parallel.
junit.jupiter.execution.parallel.enabled = true junit.jupiter.execution.parallel.mode.default = concurrent
I am running test suite SelectPakages_TestSuite_Test
which is created above examples using @SelectPackages
annotation.
Output :
If we are using JUnitPlatform
runner to run tests, the parallel tests execution feature that introduced in Junit 5.3 and configuration for parallel tests only works for Junit Jupiter tests. From the following output we can notice Junit Jupiter tests ran by different threads in parallel, but JUnit Vintage tests ran by same thread in sequential.
invalid_country_test(): ForkJoinPool-1-worker-9 simpl_dueDeligence_pass_Test(): ForkJoinPool-1-worker-7 registration_Success_Test(): ForkJoinPool-1-worker-1 payment_success_test(): ForkJoinPool-1-worker-5 simpl_dueDeligence_fail_Test(): ForkJoinPool-1-worker-7 payment_decline_test(): ForkJoinPool-1-worker-5 registration_Fail_On_DocCheck_Test(): ForkJoinPool-1-worker-1 surcharge_formula_test(): main surcharge_byCountry_test(): main surcharge_merchant_test(): main
NOTE : If you have your old tests in JUnit 4 and writing new tests in JUnit 5 with in same test application, 1. mixing JUnit 5 and Junit 4 specific annotations in single test class is not good approach, you may see errors when you run tests.
2. All the Tests class names must ends with “Test”, for example JUnit4ExampleTest
or JUnit4_Example_Test
and your JUnit 4 test methods must be defined as public
.
6. Conclusion
In this guide we have covered, how to create Test Suites for JUnit 5 and JUnit 4 test cases in Junit 4 environment and run them by using JUnitPlatform runner. And also we covered an experimental test for running parallel tests.
You can checkout source code from our github repository.
You also might be interested in following examples :
- Junit 5 Dynamic Tests
- Junit 5 tags and filter test cases for execution
- Junit 5 Timeout tests
- Junit 5 Repeated tests
- Junit 5 parameterized test
- Custom ParameterResolver.
Nice article. I have a query,if i want to use gradle instead of maven then what should include in build.gradle file.
Hi Poonam, In a single application executing JUnit 4 + JUnit 5 test suites using gradle command bit tricky, because you shouldn’t use the Junit platform to run tests, instead have to run tests in JUnit 4 environment.
Following is the build.gradle file which I have used for test all the examples in this tutorial.
plugins {
id 'java'
id 'eclipse'
}
group 'com.javabydeveloper'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
test {
// do not use useJUnitPlatform() if running with platform-runner, use it if running tests in JUnit 5 only
// Or disable JUnit platform engine
// useJUnitPlatform()
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
testImplementation 'org.junit.platform:junit-platform-runner:1.5.2'
testRuntime 'org.junit.platform:junit-platform-runner:1.5.2'
}
Following is the command to run Specific Test Suite :
$gradle test --tests ExcludeClassNamePattern_TestSuite_Test -i
This is nice article Satish..
I need some advice in parallel execution where I want to test the same feature on various browsers parallely.
So the test suite should be starting on each type of browser(e.g. Chrome, Firefox) parallely. I tried with @TestTemplate by providing the browser name parameter, but its running sequecially.
Hi Darsh, not sure which strategy you are using for parallel test execution, and also
provideTestTemplateInvocationContexts(ExtensionContext context)
method implementation ofTestTemplateInvocationContextProvider
is important. How ever you could try adding following properties injunit-platform.properties
junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = concurrent
For more options for parallel execution configuration you check out JUnit 5 parallel test execution
Running mvn test -Dtest=Junit5andJuni4_TestSuite_Test is giving following error:
[INFO] ——————————————————-
Mar 15, 2021 12:21:56 PM org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder$DefensiveAnnotatedBuilder buildRunner
WARNING: Ignoring test class using JUnitPlatform runner: com.javabydeveloper.testsuite.Junit5andJuni4_TestSuite_Test
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ————————————————————————
[INFO] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Total time: 5.908 s
[INFO] Finished at: 2021-03-15T12:21:56+01:00
How to solve it?