假设我们有Parent和Child类,我们在Parent中扩展了Specification,Child扩展了Parent。因此Child也是规范。
//Parent
@Stepwise
class Parent extends Specification{
@Shared
String name
def setupSpec(){
println "inside setupSpec"
}
def setup(){
println "inside SetUp"
}
def "testMethodOne"(){
given:
println "inside parent testmethodOne"
assert 1==2
}
def "testMethodTwo"(){
given:
println "parent testmethodTwo"
}
def cleanup(){
println " inside CleanUp"
}
def cleanupSpec(){
println "inside cleanSpec"
}
} //儿童班
//Child
@Stepwise
class Child extends Parent {
def "testMethod"(){
given:
println "inside child testmethod"
}
def "testMethodtwo"(){
given:
println "inside child testmethodTeo"
}
}
现在,如果我们正在执行Child Class,那么assert将在Parents testMethodOne中失败,并且由于我们正在使用@Stepwise,因此在断言失败后不应执行整个测试。有趣的是,父项的测试方法没有被执行,因为所有方法都是子进程被执行而不执行,因为断言失败。
如果我错过了什么,请告诉我。
答案 0 :(得分:1)
package spock.lang;
import java.lang.annotation.*;
import org.spockframework.runtime.extension.ExtensionAnnotation;
import org.spockframework.runtime.extension.builtin.StepwiseExtension;
/**
* Indicates that a spec's feature methods should be run sequentially
* in their declared order (even in the presence of a parallel spec runner),
* always starting from the first method. If a method fails, the remaining
* methods will be skipped. Feature methods declared in super- and subspecs
* are not affected.
*
* <p><tt>@Stepwise</tt> is useful for specs with
* (logical) dependencies between methods. In particular, it helps to avoid
* consecutive errors after a method has failed, which makes it easier to
* understand what really went wrong.
*
* @author Peter Niederwieser
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ExtensionAnnotation(StepwiseExtension.class)
public @interface Stepwise {}
在超级规范和子规范中声明的要素方法不受影响。
测试方法在Spock中称为特征方法。所以一切都很好,因为它按照设计的方式工作。
如果您想在父测试失败时使测试失败,请在子测试中添加自定义listerner:
@Stepwise
class Child extends Parent {
def setupSpec() {
def spec = this.getSpecificationContext().currentSpec
spec.addListener(new AbstractRunListener() {
@Override
void error(ErrorInfo error) {
spec.features.each { it.skipped = true }
}
})
}
def "test"() {
given:
println "Child::test#1"
}
def "test#2"() {
given:
println "Child::test#2"
}
}