groovy Spock -运行数据表计数

iq0todco  于 2022-11-01  发布在  其他
关注(0)|答案(3)|浏览(174)

在Spock中有没有什么方法可以在使用数据表时透明地获取当前运行计数,而不需要将其作为显式输入参数?
比如说

class MathSpec extends Specification {
    def "maximum of two numbers"(int a, int b, int c) {
        expect:
        Math.max(a, b) == c
        println "this is row:" + $currentRowCount//??

        where:
        a | b | c
        1 | 3 | 3
        7 | 4 | 4
        0 | 0 | 0
    }
}
3npbholx

3npbholx1#

这真的很难看,因为iterationCount是一个私有变量,但也是可能的:

示例规范:

package de.scrum_master.app

import spock.lang.Specification
import spock.lang.Unroll

class PieceTest extends Specification {
  @Unroll
  def "do something with data table item #item"() {
    expect:
    println specificationContext
      .currentIteration
      .parent
      .iterationNameProvider
      .iterationCount

    where:
    item  | anotherItem
    "foo" | 333
    "bar" | 444
    "zot" | 555
  }
}

控制台日志:

1
2
3

请注意,这只适用于@Unroll艾德特征方法,没有该注解则不适用。

更新:通过全局Spock扩展公开迭代计数

  • 免责声明:我喜欢Spock,但我对Groovy meta编程并不流利。这也是我的第一个Spock扩展。*

您可能知道built-in Spock extensions,它们大多是注解驱动的,如@Ignore@Timeout@Stepwise@Issue@AutoCleanup,但也有一些全局扩展,手册中没有描述,但仍然存在,如ReportLogExtensionIncludeExcludeExtension
不幸的是,手册没有描述如何创建这样的扩展,但通过一些谷歌搜索和源代码研究你可以找到答案。虽然对初学者来说没什么。

全局Spock扩展名:

此扩展将动态成员iterationCount添加到每个Spock规范中。

package de.scrum_master.app

import org.spockframework.runtime.AbstractRunListener
import org.spockframework.runtime.extension.AbstractGlobalExtension
import org.spockframework.runtime.model.FeatureInfo
import org.spockframework.runtime.model.IterationInfo
import org.spockframework.runtime.model.SpecInfo

class IterationCountExtension extends AbstractGlobalExtension {
  @Override
  void visitSpec(SpecInfo spec) {
    spec.addListener(new IterationCountListener())
  }

  static class IterationCountListener extends AbstractRunListener {
    MetaClass metaClass
    int iterationCount

    @Override
    void beforeSpec(SpecInfo spec) {
      println spec.name
      metaClass = spec.reflection.metaClass
    }

    @Override
    void beforeFeature(FeatureInfo feature) {
      println "  " + feature.name
      iterationCount = 0
      metaClass.iterationCount = iterationCount
    }

    @Override
    void beforeIteration(IterationInfo iteration) {
      println "    " + iteration.name
      metaClass.iterationCount = iterationCount++
    }
  }
}

每个扩展都需要注册。所以请添加一个包含以下内容的META-INF/services/org.spockframework.runtime.extension.IGlobalExtension文件到您的测试资源中:

de.scrum_master.app.IterationCountExtension

陈列柜规格:

package de.scrum_master.app

import spock.lang.Specification
import spock.lang.Unroll

class SampleTest extends Specification {
  def "no data table"() {
    expect:
    println "      " + iterationCount
  }

  def "data table items"() {
    expect:
    println "      " + iterationCount

    where:
    item  | anotherItem
    "foo" | 333
    "bar" | 444
    "zot" | 555
  }

  @Unroll
  def "unrolled data table item"() {
    expect:
    println "      " + iterationCount

    where:
    item  | anotherItem
    "foo" | 333
    "bar" | 444
    "zot" | 555
  }

  @Unroll
  def "unrolled data table item #item"() {
    expect:
    println "      " + iterationCount

    where:
    item  | anotherItem
    "foo" | 333
    "bar" | 444
    "zot" | 555
  }
}

控制台日志:

SampleTest
  no data table
    no data table
      0
  data table items
    data table items
      0
    data table items
      1
    data table items
      2
  unrolled data table item
    unrolled data table item[0]
      0
    unrolled data table item[1]
      1
    unrolled data table item[2]
      2
  unrolled data table item #item
    unrolled data table item foo
      0
    unrolled data table item bar
      1
    unrolled data table item zot
      2

正如您所看到的,无论是否使用@Unroll,扩展都能正常工作。在这方面,它也比上面的quick & dirty解决方案更好。
顺便说一句,如果您希望计数从1开始而不是从0开始,只需在扩展侦听器方法beforeIteration中将表达式iterationCount++切换为++iterationCount

uemypmqf

uemypmqf2#

可以将@Unroll#iterationCount一起使用,即:

import spock.lang.*

class MathSpec extends Specification {

    @Unroll
    def "maximum of #a and #b is #c (iteration #iterationCount)"() {
        given:
        def result = Math.max(a, b)

        expect:
        result == c

        where:
        a | b | c
        1 | 3 | 3
        7 | 4 | 4
        0 | 0 | 0
    }
}

PS:不要叫你的类Math,然后试着叫Math.max;- )

j2qf4p5b

j2qf4p5b3#

只是为了更新这个答案。在spock版本2.1-groovy-3.0上验证,以获得行号,用途:

specificationContext.currentIteration.iterationIndex

A级

相关问题