Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JUnit5从CSV文件读取测试数据的最佳方法是什么?_Java_Unit Testing_Csv_Junit_Junit5 - Fatal编程技术网

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

Java 使用JUnit5从CSV文件读取测试数据的最佳方法是什么?,java,unit-testing,csv,junit,junit5,Java,Unit Testing,Csv,Junit,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

使用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);
    }
}
CSV文件示例:

column1,column2,column3
a,0,0.0
abcde,1,1.01
a-b-c,999,999.0

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

Apache commons有一个很好的CSV库,您可以使用它。
CSV代表逗号分隔的值,因此本质上您可以拆分,因为您知道使用的分隔符。如果尝试将测试数据用于多个测试,可以尝试:

List<String[]> columnValues = new ArrayList<String[]>();

@Before
public void init(){
    try {
        Scanner scanner = new Scanner(new File("myFile.csv"));
        while(scanner.hasNextLine()) {
            String[] values = scanner.nextLine().split(",");
            columnValues.add(values);
        }
    }catch(Exception e) {
        //whatever
    }
}
List columnValues=new ArrayList();
@以前
公共void init(){
试一试{
Scanner Scanner=新扫描仪(新文件(“myFile.csv”);
while(scanner.hasNextLine()){
字符串[]值=scanner.nextLine().split(“,”);
columnValues.add(值);
}
}捕获(例外e){
//随便
}
}
然后在您使用的任何测试方法中,您都可以简单地分解这些值

@Test
public void myTest(){
    //set x to 1 to avoid columns
    for(int x = 1; x < columnValues.size(); x++) {
        String col1 = columnValues.get(x)[0];
        int col2 = Integer.parseInteger(columnValues.get(x)[1]);
        double col3 = Double.parseDouble(columnValues.get(x)[2]);
        double col4 = Double.parseDouble(columnValues.get(x)[3]);
        //test values here
    }
}
@测试
公共无效myTest(){
//将x设置为1以避免列
对于(int x=1;x

或者,如果您想测试特定的行,可以使用特定的索引,或者如果您愿意,甚至可以随机化,而不是测试所有行。正如您所提到的,您也可以将此概念类似地用作测试参数。

令人惊讶的是,我发现了两种记录良好的方法,它们真正回答了我的问题

首先是来自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));
    }
}
它使用图书馆。它甚至可以测试参数值的n倍笛卡尔积“有效地测试每个可能的组合。”-请参见
@CombinedParameters
注释

第二种方法使用和@ParameterizedTest的组合,直接从。。朱尼特5

public class ReadCSVJUnitParametrized {

    @ParameterizedTest
    @CsvFileSource(resources = "/financial.csv", numLinesToSkip = 1)
    public void testLetterCountParametrized(String value, long letterCount) {
        assertEquals(letterCount, LetterCounter.countLetters(value));
    }
}
我用于测试的.csv文件:

value,letterCount
,0
a,1
..aa,2
.!@#$%^&*(,0
0123456789,0
abcdefghij0,10 
字母计数器等级:

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

我想这取决于你在测试什么?您可能应该深入了解更多细节,例如预期输入+预期输出样式。如果您想知道如何简单地读取数据,请像通常在JUnit之外那样读取数据?这当然是一个选项,但我正在寻找一种易于使用且易于配置的方法。我不想重新发明轮子。谢谢-这是一个选项,但是必须存在更适合单元测试的东西,可能类似于JUnit的@ParameterizedTest。