Spock - 运行 数据 table 计数
Spock - running data table count
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
}
}
您可以将 @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: 不要调用你的 class Math
,然后尝试调用 Math.max
;-)
这真的很难看,因为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,其中大部分是annotation-driven,例如@Ignore
、@Timeout
、@Stepwise
、@Issue
、@AutoCleanup
。但是也有手册中没有描述但仍然存在的全局扩展,例如ReportLogExtension
, IncludeExcludeExtension
.
不幸的是,手册没有描述如何创建这样的扩展,但通过一些谷歌搜索和源代码研究,您可以找到答案。不过,这对初学者来说没什么。
全球 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
,扩展都有效。在这方面,它也比上面的快速和肮脏的解决方案更好。
顺便说一句,如果您希望计数从 1 开始而不是从 0 开始,只需在扩展侦听器方法 beforeIteration
中将表达式 iterationCount++
切换为 ++iterationCount
。
只是为了更新这个答案。在 spock 版本 2.1-groovy-3.0 上验证以获取行号使用:
specificationContext.currentIteration.iterationIndex
一个
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
}
}
您可以将 @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: 不要调用你的 class Math
,然后尝试调用 Math.max
;-)
这真的很难看,因为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,其中大部分是annotation-driven,例如@Ignore
、@Timeout
、@Stepwise
、@Issue
、@AutoCleanup
。但是也有手册中没有描述但仍然存在的全局扩展,例如ReportLogExtension
, IncludeExcludeExtension
.
不幸的是,手册没有描述如何创建这样的扩展,但通过一些谷歌搜索和源代码研究,您可以找到答案。不过,这对初学者来说没什么。
全球 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
,扩展都有效。在这方面,它也比上面的快速和肮脏的解决方案更好。
顺便说一句,如果您希望计数从 1 开始而不是从 0 开始,只需在扩展侦听器方法 beforeIteration
中将表达式 iterationCount++
切换为 ++iterationCount
。
只是为了更新这个答案。在 spock 版本 2.1-groovy-3.0 上验证以获取行号使用:
specificationContext.currentIteration.iterationIndex
一个