I have been searching on any documentation if this is possible with parameterized junit4 testing
.
Basically what I have is two classes, GameEntry and Scoreboard:
public class GameEntry{ private String name; private int score; // Constructor and Getters... } public class Scoreboard{ private int numEntries = 0; private GameEntry[] board; // Constructor public Scoreboard(int capacity){ board = new GameEntry[capacity]; } // Add method - Only if entry is higher than current entries public void add(GameEntry e){ // Code here... } // Remove method // Reset method }
I’ve read about parameterized testing where you return an array of different input data Passing arrays to Parameterized JUnit, but it is not quite what I would like to do. I’m interested in running 10 different tests where I would create an input text file with gameEntries name, score values, and another text file for expected values for name, and score. I would like to keep all data out of the testing class in case I want to change the data later on. After the input, and expected files have been parsed, then I would just use Assert.assertArrayEquals( expectedResult, result )
to compare the array.
I shouldn’t have any problems doing this without a parameterized Junit
test, but then if one test fails the whole test would fail. I guess I could keep a counter to track input. I would like to write just one test to avoid DRY. Is this possible with Junit
or other testing framework
?
Advertisement
Answer
JUnit 5 has the concept of “dynamic tests”, which allows you to generate test cases at runtime.
Have a look at this example (borrowed from a JUnit 5 workshop):
class PrimeNumbersTest { @TestFactory Stream<DynamicTest> test_first_1000_prime_numbers() throws Exception { return primes().mapToObj(prime -> DynamicTest.dynamicTest( // Test case name. "Prime: " + prime, // Test case content. () -> assertTrue(PrimeNumbers.isPrime(prime)))); } private LongStream primes() throws Exception { Path primesTxt = Paths.get(getClass().getResource("/primes.txt").toURI()); return Files.lines(primesTxt).mapToLong(Long::parseLong); } }
test_first_1000_prime_numbers()
uses @TestFactory
to create a test case for each prime number returned by primes()
, which loads them from the external resource primes-1000.txt
. For example, IntelliJ displays this as follows:
So, you could dynamically create a test case for each of your setups. This keeps the test data out of the test class and only those tests will fail that contain failed assertions.
Have a look at the user guide or this excellent blog post for further information, but bear in mind that JUnit 5 is still under development.