Groovy 如何在@Stepwise Spock规范中重用特征方法?

Groovy 如何在@Stepwise Spock规范中重用特征方法?,groovy,spock,Groovy,Spock,我有两个Spock规范,都是从不同的起点测试一个很长的过程,所以就像 @Stepwise class FooSpec extends Specification { def "setup1"() {...} def "setup2"() {...} def "common1"() {...} def "common2"() {...} ... } @Stepwise class BarSpec extends Specification { de

我有两个Spock规范,都是从不同的起点测试一个很长的过程,所以就像

@Stepwise
class FooSpec extends Specification {
    def "setup1"() {...}
    def "setup2"() {...}
    def "common1"() {...}
    def "common2"() {...}
    ...
}

@Stepwise
class BarSpec extends Specification {
    def "setup3"() {...}
    def "setup4"() {...}
    def "common1"() {...}
    def "common2"() {...}
    ...
}
现在,我想重构我的代码,以消除所有在不同设置之后执行的公共*特性方法的重复


我尝试使用子类化,但超类的特性方法是在子类的特性方法之前执行,而不是在子类的特性方法之后执行。我还尝试编写自己的Spock扩展(Groovy 2的Spock版本0.7),但找不到实现我所需行为的方法。

common*
方法放在基类中,并使用
setupSpec()
方法(而不是
setup*
方法)添加两个子类.

参考
逐步扩展的源代码,我终于想出了自己的解决方案:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@ExtensionAnnotation(BeforeSuperExtension)
@interface BeforeSuper {}
此注释标记了
@逐步测试中的功能方法,该测试应在
super
的功能方法之前执行

扩展实现将相应地重新安排执行顺序:

class BeforeSuperExtension extends AbstractAnnotationDrivenExtension<BeforeSuper>
{
    def beforeSuper = []

    @Override
    void visitFeatureAnnotation(BeforeSuper annotation, FeatureInfo feature)
    {
        beforeSuper << feature
    }

    @Override
    void visitSpec(SpecInfo spec)
    {
        def superFeatures = spec.superSpec.allFeaturesInExecutionOrder
        def afterSuper = spec.features - beforeSuper

        (beforeSuper + superFeatures + afterSuper).eachWithIndex { f, i ->
            f.executionOrder = i
        }
    }
}
类BeforeSuperExtension扩展了AbstractAnnotationDrivenExtension
{
def BEFORESPER=[]
@凌驾
无效visitFeatureAnnotation(超级注释之前,FeatureInfo功能)
{
超级之前
f、 执行顺序=i
}
}
}

我实施了相反的策略,使用注释
@AfterSubSpec
告诉超类中的常用方法在子类中的方法之后运行:

class AfterSubSpecExtension extends AbstractAnnotationDrivenExtension<AfterSubSpec> {

    def afterSub = []

    @Override
    void visitFeatureAnnotation(AfterSubSpec annotation, FeatureInfo feature) {
        afterSub << feature
    }

    @Override
    void visitSpec(SpecInfo spec) {
        def subSpecFeatures = spec.bottomSpec.allFeaturesInExecutionOrder - afterSub

        (subSpecFeatures + afterSub).eachWithIndex { f, i -> f.executionOrder = i }
    }
}
class-AfterSubSpecExtension扩展了AbstractAnnotationDrivenExtension{
def afterSub=[]
@凌驾
无效visitFeatureAnnotation(子项注释后,FeatureInfo要素){
afterSub f.executionOrder=i}
}
}

设置非常复杂,可以拆分为多个功能方法。我希望保留这种粒度。