【问题标题】:Data driven tests in SpockSpock 中的数据驱动测试
【发布时间】:2016-10-09 06:43:24
【问题描述】:

我正在将一些 JUnit 测试重写为 Spock,以利用数据驱动的测试风格。

我正在为如何提供动态验证而苦苦挣扎。

这是我目前所拥有的:

def "domestic rules"(from, to, oneWay, check) {

    expect:
    String mealResponse = getMealResponse(new BookingOptions.BookingOptionsBuilder().setFrom(from).setTo(to).setOneWay(oneWay).build());
    check(mealResponse)

    where:
    from  | to    | oneWay || check
    'MNL' | 'PEK' | true   || assertNoMeals()
}

def assertNoMeals = {
    assert JsonAssert.with(it)
            .assertThat('$.links', hasSize(1))
            .assertThat('$.links[0].rel', is("http://localhost:9001/api/docs/rels/ink/meal-allocations"))
            .assertThat('$.links[0].uri', startsWith("http://localhost:9001/api/tenants/acme/meals/allocations/"));
}

不幸的是,我在第一行数据的行收到了 NullPointerException。

我猜那是因为当时正在运行闭包,而不是刚刚声明。

有没有办法更好地做到这一点?

【问题讨论】:

标签: groovy spock


【解决方案1】:

如果您真的想让您的测试难以维护并继续在示例中使用闭包作为“值”,那么请执行以下操作:

def "domestic rules"() {

  when:
  String mealResponse = getMealResponse(new BookingOptions.BookingOptionsBuilder().setFrom(from).setTo(to).setOneWay(oneWay).build())

  then:
  check(mealResponse)

  where:
  from  | to    | oneWay || check
  'MNL' | 'PEK' | true   || this.&assertNoMeals 
}

boolean assertNoMeals(mealResponse) {
  assert JsonAssert.with(mealResponse)
        .assertThat('$.links', hasSize(1))
        .assertThat('$.links[0].rel',  is("http://localhost:9001/api/docs/rels/ink/meal-allocations"))
        .assertThat('$.links[0].uri',   startsWith("http://localhost:9001/api/tenants/acme/meals/allocations/"))
  return true // pass!
}

我建议你在写一些更合理的东西之前先学习 Groovy 和 Spock。这并不难,但至少需要几个小时!

【讨论】:

  • 刚刚发现你实际上需要让assertNoMeals返回一个布尔值(true)才能通过测试...Spock通常识别void方法,但在这种情况下它不识别方法引用返回无效。
  • 不知道为什么你认为这是一个坏主意。参数化测试很有用,虽然它们是 JSON 断言,但我只是有不同的断言。
  • 如果你有不同的断言,它们在不同的测试中可能会更好
【解决方案2】:

改变

def "domestic rules"(from, to, oneWay, check) {

@Unroll
def "domestic rules from #from to #to one way #oneWay"() {

【讨论】:

    【解决方案3】:
    def "domestic rules"() {
    
      when: 'get meals using certain parameters'
      String mealResponse = getMealResponse(new BookingOptions.BookingOptionsBuilder().setFrom(from).setTo(to).setOneWay(oneWay).build())
    
      then: 'the json response should contain some contents (improve the message here!)'
      JsonAssert.with(mealResponse)
            .assertThat('$.links', hasSize(1))
            .assertThat('$.links[0].rel', is(somethingToUseInAssertions))
    
    
      where:
      from  | to    | oneWay || somethingToUseInAssertions
      'MNL' | 'PEK' | true   || 'just some example'
    }
    

    以上内容应该可以帮助您走上正轨。请注意,您应该仅在示例中具有一些值。如果您在断言中需要一些逻辑,请使用一个值来指示需要进行哪种断言...但是使用闭包作为示例是一个非常糟糕的主意。

    【讨论】:

    • 我正在寻找一种允许我添加更多行并具有不同断言的解决方案。您的示例被硬编码为单行断言。
    • 为每种类型的断言创建一个测试。你就是这样做的。如果每个示例都有完全不同的断言,那么这些示例属于不同的特征。
    • 我将您的答案标记为解决方案,因为我决定放弃这种方法并为每个断言集进行一个测试。我认为数据驱动的风格更适合一致的输入和输出。
    猜你喜欢
    • 2023-03-11
    • 2017-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多