Home Junit 5 JUnitPlatform runner - create JUnit 4 + JUnit 5 test suites and...

JUnitPlatform runner – create JUnit 4 + JUnit 5 test suites and run

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.

creating tests suites in Junit 5 and Junit 4 and run tests with JUnitPlatform runner

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.

JunitPlatform runner in Junit 5

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 :

  1. Junit 5 Dynamic Tests and @TestFactory annotation.
  2. Junit 5 tags and filter test cases for execution.
  3. Junit 5 Timeout tests, fail tests if not completed within time.
  4. Junit 5 Repeated tests and display Repetition info.
  5. Junit 5 parameterized tests with different argument sources.
  6. Creating a Custom ParameterResolver and built in Junit 5 Parameter Resolvers.

References

  1. JUnit 5 documentation
  2. JUnit Jupiter Parallel tests execution and Synchronization with @ResourceLock

Satish Varma
Satish Varmahttps://javabydeveloper.com
Satish is post graduated in master of computer applications and experienced software engineer with focus on Spring, JPA, REST, TDD and web development. Also founder of javabydeveloper.com. Follow him on LinkedIn or Twitter or Facebook

4 COMMENTS

    • 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

  1. 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 of TestTemplateInvocationContextProvider is important. How ever you could try adding following properties in junit-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

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Stay in Touch

Categories

Related Articles