使用 JUnit 5 从 CSV 文件读取测试数据的最佳方法是什么?

Pio*_*ski 3 java csv junit unit-testing junit5

使用 JUnit 5 从 CSV 文件读取测试数据的最佳/建议方法是什么?

假设一行是一个测试用例,一列是一个参数,列数是固定的,不同列可以有不同的(基本)类型:String、int、double。

一个例子是:

public class Test{

    @Test
    // ready to use annotation that may load parameters from each line 
    public void shouldCalculateDiscount(String column1, long column2, double column3) {
        assertEquals(5, column1.length());
        assertEquals(column3, column2, 0.0001);
    }
}
Run Code Online (Sandbox Code Playgroud)

CSV 文件示例:

column1,column2,column3
a,0,0.0
abcde,1,1.01
a-b-c,999,999.0
Run Code Online (Sandbox Code Playgroud)

使用注释的方法将是完美的,可能类似于 JUnit 的 @ParameterizedTest。

Pio*_*ski 7

令人惊讶的是,我发现了两种有据可查的方法真正回答了我的问题。

一个来自Tomek Kaczanowski 所著的《使用 JUnit 和 Mockito 进行实用单元测试》一书。他建议使用以下内容:

@RunWith(JUnitParamsRunner.class)
public class ReadCSVJunitParamsTest {

    @Test
    @FileParameters(value = "classpath:financial.csv", mapper = CsvWithHeaderMapper.class)
    public void testLetterCount(String value, long letterCount) {
        assertEquals(letterCount, LetterCounter.countLetters(value));
    }
}
Run Code Online (Sandbox Code Playgroud)

它使用JUnitParams库。它甚至可以测试参数值的 n 倍笛卡尔积“有效地测试每个可能的组合。 ” - 请参阅@CombinedParameters注释。

第二种方法使用@CsvSource和 @ParameterizedTest 的组合,直接来自 JUnit 5。

public class ReadCSVJUnitParametrized {

    @ParameterizedTest
    @CsvFileSource(resources = "/financial.csv", numLinesToSkip = 1)
    public void testLetterCountParametrized(String value, long letterCount) {
        assertEquals(letterCount, LetterCounter.countLetters(value));
    }
}
Run Code Online (Sandbox Code Playgroud)

我用于测试的.csv文件:

value,letterCount
,0
a,1
..aa,2
.!@#$%^&*(,0
0123456789,0
abcdefghij0,10 
Run Code Online (Sandbox Code Playgroud)

LetterCounter类:

public class LetterCounter {
    public static long countLetters(String value) {
        if (value == null) {
            return 0;
        }
        return value.chars().filter(Character::isLetter).count();
    }
}
Run Code Online (Sandbox Code Playgroud)