我如何 运行 使用多个输入进行相同的测试?

How do I run the same test with multiple inputs?

我想做如下的批量测试,但是如果有错误,它没有告诉我错误发生在i的哪个值。

@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);
    }
}

这是一个示例,说明如果我 运行 按原样编写代码会发生什么:

这是我希望发生的事情的示例:

我看过参数化测试 in this tutorial,但是我不知道这是否是我想要的路线。

有什么建议吗?


我不认为这个问题与这些问题重复:

Running the same JUnit test case multiple time with different data

Java unit test for different input data

进行此测试的正确方法是使用您在问题中描述的参数化测试。但是,你说你不想那样做。因此,您始终可以为失败消息使用 String 消息参数。

您似乎在这一行中使用了 assertEquals(double, expected, double actual, double delta)

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

相反,您可以使用 assertEquals(String message, double expected, double actual, double delta) 为自己提供信息更丰富的错误消息,例如

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

这会给您一条错误消息,例如:

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

Durron 的回答导致通过 @Parameters 进行参数化 JUnit 测试。这是一个很好的答案,非常适合这个问题。然而,我一直沿着这条路走下去,发现它创建了复杂且难以阅读的测试。

理论是 JUnit 中的替代方案:junit.org/apidocs/org/junit/experimental/theories/Theories.html

如果您愿意远离 JUnit,testNG 的数据提供程序非常通用:testng.org/doc/documentation-main.html#parameters-dataproviders

尝试JUnitParams。您的测试将如下所示:

@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);
        }
    }

当您 运行 测试时,您将得到一份您想要的报告。更好的是,与标准 JUnit Parametrized 运行 不同,JUnitPramsRunner 报告不仅包含测试用例索引,还包含每个用例的参数(抱歉,我没有足够的声誉来 post 截图)。

注意:您需要添加依赖项:

  • Gradle:

    testCompile 'pl.pragmatists:JUnitParams:1.0.2'
    
  • 马文:

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