gpt4 book ai didi

unit-testing - Spock:从 CSV 文件读取测试数据

转载 作者:行者123 更新时间:2023-12-01 16:28:24 24 4
gpt4 key购买 nike

我正在尝试编写一个优雅的 Spock 规范,该规范将从 CSV 文件中读取非常大的测试数据,而无需将所有数据加载到内存中。我正在寻求您的反馈,以了解如何做得比我目前所做的更好。

假设我的简化 CSV 文件如下所示:-

1,2
3,4
5,6

断言是“第1列”+ 1 ==“第2列”

我使用 OpenCSV 进行 CSV 解析只是因为实际的 CSV 文件包含带有双引号和逗号等特殊字符的字符串,而通过用逗号分割字符串进行基本解析是行不通的。

<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.3</version>
</dependency>

尝试 1

我的第一次尝试是循环遍历 CSV 并对每一行执行断言。虽然这种方法有效,但我无法使用 @Unroll 将每个断言隔离到单独的独立测试中。

def "read from csv"() {
expect:
def reader = new CSVReader(...)
def fields

while ((fields = reader.readNext()) != null) {
def firstNum = Integer.valueOf(fields[0])
def secondNum = Integer.valueOf(fields[1])

firstNum + 1 == secondNum
}
}

尝试 2

此尝试允许我利用@Unroll,但这需要将整个数据加载到内存中,这是我首先要避免的。

@Unroll
def "read from csv"() {
expect:
Integer.valueOf(firstNum as String) + 1 == Integer.valueOf(secondNum as String)

where:
[firstNum, secondNum] << new CSVReader(...).readAll()
}

尝试3

阅读后http://spock-framework.readthedocs.org/en/latest/data_driven_testing.html#data-pipes ,我可以创建一个实现Iterable的对象...并且Spock只会指示数据提供者仅在需要时查询下一个值,这正是我想要的。

@Unroll
def "read from csv"() {
given:
CSVParser csvParser = new CSVParser()

expect:
def fields = csvParser.parseLine(line as String)
def firstNum = Integer.valueOf(fields[0])
def secondNum = Integer.valueOf(fields[1])

firstNum + 1 == secondNum

where:
line << new Iterable() {
@Override
Iterator iterator() {
return new Scanner(...)
}
}
}

这个尝试还不错,但看起来很奇怪,我必须在 expect block 中进行一些 CSV 解析,这混淆了这里的实际意图,即执行断言。

尝试4

我的最后一次尝试几乎创建了一个迭代器包装器,它将字段作为单独的变量返回,但代码很难阅读,除非我将 Iterable 类提取到单独的 API 中。

@Unroll
def "read from csv"() {
expect:
Integer.valueOf(firstNum as String) + 1 == Integer.valueOf(secondNum as String)

where:
[firstNum, secondNum] << new Iterable() {
@Override
Iterator iterator() {
new Iterator() {
def reader = new CSVReader(...)

def fields

@Override
boolean hasNext() {
fields = reader.readNext()
return fields != null
}

@Override
Object next() {
return fields
}

@Override
void remove() {
throw new UnsupportedOperationException()
}
}
}
}
}

问题

我的问题是...您将如何解决这个问题?有更好的方法(或者更好的 CSV 库)吗?我知道 Apache Commons CSV 可能是我所知道的唯一实现 Iterable 的解析器,但它长期以来一直是 SNAPSHOT

非常感谢。

最佳答案

编写实用程序类CSVFile实现 Iterable<Iterable<String>> (或Iterable<Iterable<Integer>>)。然后使用where: [firstNum, secondNum] << new CSVFile("path/to/file") .

关于unit-testing - Spock:从 CSV 文件读取测试数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25189342/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com