如何使用多个输入数据测试数组是否相等

时间:2017-05-22 15:49:56

标签: java unit-testing parameterized

我一直在搜索任何文档,如果可以使用参数化junit4 testing

基本上我所拥有的是两个类,GameEntry和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
}

我已经阅读了有关参数化测试的内容,其中您返回了不同输入数据Passing arrays to Parameterized JUnit的数组,但这并不是我想要做的。我有兴趣运行10个不同的测试,我将创建一个输入文本文件,其中包含gameEntries名称,分数值和另一个文本文件,用于名称和分数的预期值。我希望将所有数据保留在测试类之外,以防我以后想要更改数据。在输入和预期的文件被解析之后,我只会使用Assert.assertArrayEquals( expectedResult, result )来比较数组。

如果没有参数化Junit测试,我不应该遇到任何问题,但如果一个测试失败,整个测试都会失败。我想我可以保留一个计数器来跟踪输入。我想写一个测试来避免DRY。 Junit或其他testing framework是否可以这样做?

1 个答案:

答案 0 :(得分:1)

JUnit 5具有"动态测试"的概念,允许您在运行时生成测试用例。

看一下这个例子(借鉴JUnit 5 workshop):

public class PrimeNumbersTest {

    @TestFactory
    Stream<DynamicTest> test_first_1000_prime_numbers() throws Exception {
        return primes().mapToObj(p -> DynamicTest.dynamicTest(
                // Test case name.
                "Prime: " + p,
                // Test case content.
                () -> assertTrue(PrimeNumbers.isPrime(p))));
    }

    private LongStream primes() throws Exception {
        return Files.lines(Paths.get(getClass().getResource("/primes-1000.txt").toURI()))
                .mapToLong(Long::parseLong);
    }

}

test_first_1000_prime_numbers()使用@TestFactoryprimes()返回的每个素数创建一个测试用例,从外部资源primes-1000.txt加载它们。例如,IntelliJ显示如下:

enter image description here

因此,您可以为每个设置动态创建测试用例。这样可以将测试数据保留在测试类之外,只有那些包含失败断言的测试才会失败。

请查看user guide或此优秀blog post以获取更多信息,但请记住,JUnit 5仍处于开发阶段。