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

2023-12-10

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

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

1,2
3,4
5,6

断言是"column 1" + 1 == "column 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块混淆了这里的实际意图,即执行断言。

尝试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()
                }
            }
        }
    }
}

Question

我的问题是......你会如何解决这个问题?有更好的方法(或者更好的 CSV 库)吗?我知道 Apache Commons CSV 可能是我所知道的唯一实现的解析器Iterable,但这已经是一个SNAPSHOT许久。

非常感谢。


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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spock:从 CSV 文件读取测试数据 的相关文章

  • 在 Eclipse 中编译 Groovy 文件

    我的 java web 项目包含一些 Groovy 代码 但 Eclipse 无法识别 Groovy 文件 也无法从中生成任何类 我已经在 Eclipse 中安装了 Groovy 插件 在我的 Windows 机器中安装 Groovy 并设
  • UnitTest HttpResponse WriteAsync 和 CopyToAsync

    我想对下一个方法进行单元测试 public static async Task SetResponseBody HttpResponse response string message var originalResponseBody re
  • 使用 fgetcsv 循环遍历 csv

    我有一个包含 3 列的 csv 文件 电子邮件地址 名 and 姓 我已经到了可以使用以下代码打印数组的阶段 这会打印数组 因此每个字段都在一行中 我希望它打印的只是该行第一列中的值 这是如何完成的 关于 fgetcsv 的文档对我 相对初
  • 访问静态范围内的全局变量

    有没有办法从同一脚本中声明的类的静态方法访问脚本中声明的全局变量 例如 def s 12345 class MyClass static def method println s 因为这样它会因错误而失败 You attempted to
  • 使用 Minitest 测试自定义验证器

    我有多个带有电子邮件验证的模型 因此 我将验证提取到自定义验证器中 我按照以下教程做到了这一点导轨指南 http guides rubyonrails org active record validations html custom va
  • 如何对嵌套函数进行单元测试? [复制]

    这个问题在这里已经有答案了 您将如何对嵌套函数进行单元测试f1 在下面的例子中 def f def f1 return 1 return 2 或者需要测试的函数不应该嵌套吗 有一个类似的问题这个链接 https stackoverflow
  • Moq - 如何对方法中引用的更改进行单元测试

    另一天 另一个问题 我的服务层有以下方法 public MatchViewData CreateMatch string user var matchViewData HasReachedMaxNumberOfMatchesLimit us
  • Android Excel CSV 的 MIME 数据类型是什么?

    我尝试了 text csv 甚至 application vnd ms excel 但 Excel 不会显示在选择列表中 很多其他应用程序也可以 void shareCsv Uri uri Context context Intent in
  • 如何使用 google test for C++ 来运行数据组合

    我有一个单元测试 需要针对 200 种可能的数据组合运行 生产实现在配置文件中有要测试的数据 我知道如何模拟这些值 我更喜欢为每个组合编写单独的测试用例 并使用某种方式循环数据 有没有使用 Google test for C 的直接方法 您
  • Coffeescript + 单元测试:全局变量?

    我正在尝试使用 Jasmine 对用 CoffeeScript 编写的小型应用程序进行单元测试 我发现很多资料都说单元测试可以在从 CoffeeScript 编译的 JS 上完美地完成 如果所有内容都包装在匿名函数中以避免污染名称空间 如何
  • 如何从CDN注入外部JS到Jest单元测试?

    我有 npm 和 webpack 的反应应用程序 我正在尝试向其添加单元测试 我使用的是包含在我的index html 中的CDN 的jQuery 而不是使用节点模块 我在组件中使用 jQueryTest1我向其中添加了单元测试用例 现在
  • 如果“testthat”测试在“R”中失败,则打印自定义诊断信息

    I use a testthat单元测试来检查是否data frame函数返回的结果与我期望它返回的结果相同 如果测试失败 testthat打印一些诊断信息 例如 MyFunction df orig is not identical to
  • 如何将复杂的 csv 文件导入到 Matlab 中的数值向量

    我想知道我们应该如何读取由字符串 双精度数和字符等组成的复杂 csv 文件 例如 您能否提供一个可以在此 csv 文件中提取数值的成功命令 Click here http www ecb europa eu stats money yc d
  • 寻找自定义 SynchronizationContext 的示例(单元测试所需)

    我需要定制同步上下文 http msdn microsoft com en us library system threading synchronizationcontext aspx that 拥有一个运行 Posts 和 Sends
  • AttributeError:“模块”对象没有属性“TestCase”

    我有名为 test py 的unittest 文件 My code import unittest class Test unittest TestCase def myTest self a 1 self assertEqual a 1
  • 在iPhone上将CSV文件读入sqlite3

    有没有办法在iPhone上将CSV文件读入sqlite3 sqlite3 是否有类似于 SQL 命令的功能 LOAD DATA LOCAL INFILE file csv INTO TABLE TABLENAME FIELDS TERMIN
  • Googletest 参数化测试崩溃

    我刚刚了解到googletest 中的值参数化单元测试 https github com google googletest blob master docs advanced md value parameterized tests并想在
  • 如何使用 Jest 测试对象键和值的相等性?

    我有一个mapModule我在其中导入组件并导出它们 import ComponentName from components ComponentName export default name ComponentName 我该如何测试ma
  • 如何使用 jUnit 将测试用例添加到套件中?

    我有 2 个测试类 都扩展了TestCase 每个类都包含一堆针对我的程序运行的单独测试 如何将这两个类 以及它们拥有的所有测试 作为同一套件的一部分执行 我正在使用 jUnit 4 8 在 jUnit4 中你有这样的东西 RunWith
  • pandas.read_csv 将列名移动一倍

    我正在使用位于的 ALL zip 文件here http www fec gov disclosurep PDownload do 我的目标是用它创建一个 pandas DataFrame 但是 如果我跑 data pd read csv

随机推荐