Spock - 运行数据表计数

时间:2017-01-25 10:00:35

标签: groovy spock

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
    }
}

2 个答案:

答案 0 :(得分:4)

这真的很难看,因为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 ed功能方法,而不是没有该注释。

更新:通过全球Spock扩展程序公开迭代次数

免责声明:我喜欢Spock,但我不熟悉Groovy元编程。这也是我的第一个Spock扩展。

您可能知道built-in Spock extensions主要是注释驱动的,例如@Ignore@Timeout@Stepwise@Issue@AutoCleanup。但也存在全局扩展,这些扩展未在手册中描述但仍然存在,例如, ReportLogExtensionIncludeExcludeExtension

不幸的是,手册没有描述如何创建这样的扩展,但通过一些谷歌搜索和源代码研究,你可以找到。但是对于初学者来说没什么。

Global Spock扩展程序:

此扩展为每个Spock规范添加了动态成员iterationCount

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,扩展程序都能正常运行。在这方面它也比快速&更好。从上面肮脏的解决方案。

BTW,如果您希望计数从1开始而不是从0开始,只需在扩展侦听器方法iterationCount++中将表达式++iterationCount切换为beforeIteration

答案 1 :(得分:1)

您可以将@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; - )