How to run the same tests with multiple inputs?

I want to run a batch test, for example, the following, however, if there is an error, it does not tell me what value i has the error.

 @Test public void simpleMovingAverageBatch() { for (int i = 1; i < 61; ++i) { simpleMovingAverage(i); } } public void simpleMovingAverage(int days) { double sma = -1; int size = stock.getCloses().size(); stock.calcSMA(days); // <- code that I'm testing // first days should be -1 for (int index = size - 1; index >= size - days + 1; --index) { assertEquals(-1, stock.getSMA(days, index), 0.001); } for (int index = size - days - 1; index >= 0; --index) { sma = 0.0; for (int i = 0; i < days; ++i) { sma += stock.getCloses().get(index + i); } sma /= days; assertEquals(sma, stock.getSMA(days, index), 0.001); } } 

This is an example of what happens if I run the code as is:

Not what I want!

This is an example of what I want:

Something like this!

I looked at Parameterized Tests in this tutorial , but I don’t know if I want to take this route.

Any tips?


I do not think this question duplicates them:

Running the same JUnit test multiple times with different data

Java unit test for different input

+4
source share
3 answers

The correct way to conduct this test is to use a parameterized test, as you describe in your question. However, you said you did not want to do this. Therefore, instead, you can always use the String message argument for the error message.

It looks like you are using assertEquals(double, expected, double actual, double delta) in this line:

 assertEquals(-1, stock.getSMA(days, index), 0.001); 

Instead, you can use assertEquals(String message, double expected, double actual, double delta) to give a more informative error message, like

 assertEquals(String.format("For index %d,", index), -1, stock.getSMA(days, index), 0.001); 

This will give you an error message like:

 java.lang.AssertionError: For index 15, expected:<-1.0> but was:<0.0> 
+1
source

Durron's answer leads to parameterized JUnit tests via @Parameters . This is a great answer and fits the question perfectly. However, I was on this road and found that it created complex and difficult to read tests.

Theories are an alternative at JUnit: junit.org/apidocs/org/junit/experimental/theories/Theories.html

If you want to deviate from JUnit, the dataproviders testNG are pretty universal: testng.org/doc/documentation-main.html#parameters-dataproviders

+2
source

Try JUnitParams . Your test will look like this:

 @RunWith(JUnitParamsRunner.class) public class ExampleTest { // this method provides parameters for simpleMovingAverage public static Iterable<Integer> parametersForSimpleMovingAverage() { return IntStream.rangeClosed(1, 61).boxed().collect(Collectors.toList()); } @Parameters @Test public void simpleMovingAverage(int days) { double sma = -1; int size = stock.getCloses().size(); stock.calcSMA(days); // <- code that I'm testing // first days should be -1 for (int index = size - 1; index >= size - days + 1; --index) { assertEquals(-1, stock.getSMA(days, index), 0.001); } for (int index = size - days - 1; index >= 0; --index) { sma = 0.0; for (int i = 0; i < days; ++i) { sma += stock.getCloses().get(index + i); } sma /= days; assertEquals(sma, stock.getSMA(days, index), 0.001); } } 

And when you run the test, you will get a report as you like. Even better, unlike the standard JUnit Parametrized runner. The JUnitPramsRunner report will contain not only the index of the test case, but also a parameter for each case (sorry, I do not have enough reputation to post a screenshot).

Note: you will need to add a dependency:

  • Gradle:

     testCompile 'pl.pragmatists:JUnitParams:1.0.2' 
  • Maven:

     <dependency> <groupId>pl.pragmatists</groupId> <artifactId>JUnitParams</artifactId> <version>1.0.4</version> <scope>test</scope> </dependency> 
+2
source

All Articles