Monday 23 August 2021

Junit5: @TestFactory: Dynamic Tests

DynamicTest is a test case generated at runtime, which is composed of a display name and an Executable.

@API(status = MAINTAINED, since = "5.3")
public class DynamicTest extends DynamicNode {

	public static DynamicTest dynamicTest(String displayName, Executable executable) {
		return new DynamicTest(displayName, null, executable);
	}

	public static DynamicTest dynamicTest(String displayName, URI testSourceUri, Executable executable) {
		return new DynamicTest(displayName, testSourceUri, executable);
	}

	.......
	.......

}

 

What is Executable?

Executable is a @FunctionalInterface, which means that the implementations of dynamic tests can be provided as lambda expressions or method references.

 

How to create dynamic tests?

Dynamic tests are created using factory methods. @TestFactory method itself is not a test case, it is a factory of test cases. A @TestFactory method must return a Stream, collection, iterator or iterable of DynamicTest instances.

 

Example

 

@TestFactory
Collection<DynamicTest> dynamicTestsFromCollection() {
	return Arrays.asList(
			dynamicTest("1st dynamic test", () -> assertEquals("olleh", reverseString("hello"))),
			dynamicTest("2nd dynamic test", () -> assertEquals(4, sum(2, 2))),
			dynamicTest("3rd dynamic test", () -> assertEquals(5, length("Hello"))));
}

 

Above snippet create 3 dynamic tests.

 

Find the below working application.

 

DynamicTestDemo1.java

package com.sample.app;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;

import java.util.Arrays;
import java.util.Collection;

import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;

public class DynamicTestDemo1 {

	@TestFactory
	Collection<DynamicTest> dynamicTestsFromCollection() {
		return Arrays.asList(
				dynamicTest("1st dynamic test", () -> assertEquals("olleh", reverseString("hello"))),
				dynamicTest("2nd dynamic test", () -> assertEquals(4, sum(2, 2))),
				dynamicTest("3rd dynamic test", () -> assertEquals(5, length("Hello"))));
	}

	private static String reverseString(String str) {
		return new StringBuilder().append(str).reverse().toString();
	}

	private static int sum(int a, int b) {
		return a + b;
	}

	private static int length(String str) {
		if (str == null)
			return 0;
		return str.length();
	}

}

  Run above test class, you can observe three tests are executed in junit window.

 


 

Some more examples to understand dynamic tests.

 

Example 1: Dynamic tests from a collection.

@TestFactory
Collection<DynamicTest> dynamicTestsFromCollection() {
	return Arrays.asList(
			dynamicTest("1st dynamic test", () -> assertEquals("olleh", reverseString("hello"))),
			dynamicTest("2nd dynamic test", () -> assertEquals(4, sum(2, 2))),
			dynamicTest("3rd dynamic test", () -> assertEquals(5, length("Hello"))));
}


Example 2: Dynamic test from an iterable.

@TestFactory
Iterable<DynamicTest> dynamicTestsFromIterable() {
	return Arrays.asList(
			dynamicTest("1st dynamic test", () -> assertEquals("olleh", reverseString("hello"))),
			dynamicTest("2nd dynamic test", () -> assertEquals(4, sum(2, 2))),
			dynamicTest("3rd dynamic test", () -> assertEquals(5, length("Hello"))));
}


Example 3: Dynamic test from iterator.

@TestFactory
Iterator<DynamicTest> dynamicTestsFromIterator() {
	return Arrays.asList(
			dynamicTest("1st dynamic test", () -> assertEquals("olleh", reverseString("hello"))),
			dynamicTest("2nd dynamic test", () -> assertEquals(4, sum(2, 2))),
			dynamicTest("3rd dynamic test", () -> assertEquals(5, length("Hello")))).iterator();
}


Example 4: Dynamic test from an array.

@TestFactory
DynamicTest[] dynamicTestsFromArray() {
	return new DynamicTest[] {
			dynamicTest("1st dynamic test", () -> assertEquals("olleh", reverseString("hello"))),
			dynamicTest("2nd dynamic test", () -> assertEquals(4, sum(2, 2))),
			dynamicTest("3rd dynamic test", () -> assertEquals(5, length("Hello")))};
}


Example 5: Dynamic test from a stream.

@TestFactory
Stream<DynamicTest> dynamicTestsFromIntStream() {
	 return IntStream
			 .iterate(0, n -> n + 2)
			 .limit(5)
			 .mapToObj(n -> dynamicTest("isEven : " + n, () -> assertTrue(n % 2 == 0)));
}


Find the below working application.

 

DynamicTestDemo2.java

package com.sample.app;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;

public class DynamicTestDemo2 {

	@TestFactory
	Collection<DynamicTest> dynamicTestsFromCollection() {
		return Arrays.asList(
				dynamicTest("1st dynamic test", () -> assertEquals("olleh", reverseString("hello"))),
				dynamicTest("2nd dynamic test", () -> assertEquals(4, sum(2, 2))),
				dynamicTest("3rd dynamic test", () -> assertEquals(5, length("Hello"))));
	}
	
	@TestFactory
	Iterable<DynamicTest> dynamicTestsFromIterable() {
		return Arrays.asList(
				dynamicTest("1st dynamic test", () -> assertEquals("olleh", reverseString("hello"))),
				dynamicTest("2nd dynamic test", () -> assertEquals(4, sum(2, 2))),
				dynamicTest("3rd dynamic test", () -> assertEquals(5, length("Hello"))));
	}
	
	@TestFactory
	Iterator<DynamicTest> dynamicTestsFromIterator() {
		return Arrays.asList(
				dynamicTest("1st dynamic test", () -> assertEquals("olleh", reverseString("hello"))),
				dynamicTest("2nd dynamic test", () -> assertEquals(4, sum(2, 2))),
				dynamicTest("3rd dynamic test", () -> assertEquals(5, length("Hello")))).iterator();
	}
	
	@TestFactory
	DynamicTest[] dynamicTestsFromArray() {
		return new DynamicTest[] {
				dynamicTest("1st dynamic test", () -> assertEquals("olleh", reverseString("hello"))),
				dynamicTest("2nd dynamic test", () -> assertEquals(4, sum(2, 2))),
				dynamicTest("3rd dynamic test", () -> assertEquals(5, length("Hello")))};
	}
	
	 @TestFactory
	 Stream<DynamicTest> dynamicTestsFromIntStream() {
		 return IntStream
				 .iterate(0, n -> n + 2)
				 .limit(5)
				 .mapToObj(n -> dynamicTest("isEven : " + n, () -> assertTrue(n % 2 == 0)));
	}

	private static String reverseString(String str) {
		return new StringBuilder().append(str).reverse().toString();
	}

	private static int sum(int a, int b) {
		return a + b;
	}

	private static int length(String str) {
		if (str == null)
			return 0;
		return str.length();
	}

}


Run above test class, you will see the results in junit window.









 

 

 

 

Previous                                                    Next                                                    Home

No comments:

Post a Comment