标记Geb类/测试以进行排除

时间:2015-03-18 16:15:10

标签: grails spock geb

我正在尝试创建一种简单的方法,根据没有可选的“标记”来排除Geb测试的运行。

在我的grails项目中,我为我的geb文件创建了一个“test / functional”目录。在这个目录中,我有GebConfig.groovy和SpockConfig.groovy文件。我知道SpockConfig.groovy当前遇到的问题是能够解析项目中的类,并且只识别BuildConfig依赖项中提供的类。因此,我创建并jar了一个注释类“Tags”并将其包含在依赖项中。我现在可以通过以下方式在我的Geb测试中使用此注释:

@Tags("regression")
@Tags(["smoke", "regression"])
@Tags(["in-progress", "whatever-makes-sense"])

我现在想要的是SpockConfig使用@Tags注释查找“test / functional”目录中的所有类,以及每个没有System.getenv(“functional.tag”)的类。 )在tags数组中,将类添加到runner.exclude基类集合中,以便它不会执行。

我对Annotations及其处理相当新,到目前为止还没有找到一种简单的方法来执行此过程的查找逻辑。是否有现有的结构可以促进这样的过程,或者可以用什么逻辑来完成这项任务呢?

编辑:

我能够通过以下类实现此功能......

public class IgnoreUnlessExtension extends AbstractAnnotationDrivenExtension<IgnoreUnless> {
    private static final Pattern JAVA_VERSION = Pattern.compile("(\\d+\\.\\d+).*");

    private static final Object DELEGATE = new Object() {
        public Map<String, String> getEnv() {
            return System.getenv();
        }

        public Properties getProperties() {
            return System.getProperties();
        }

        public BigDecimal getJavaVersion() {
            String versionString = System.getProperty("java.version");
            Matcher matcher = JAVA_VERSION.matcher(versionString);
            if (matcher.matches()) return new BigDecimal(matcher.group(1));
            throw new InternalSpockError(versionString);
        }
    };

    @Override
    public void visitSpecAnnotation(IgnoreUnless annotation, SpecInfo spec) {
        doVisit(annotation, spec);
    }

    @Override
    public void visitFeatureAnnotation(IgnoreUnless annotation, FeatureInfo feature) {
        doVisit(annotation, feature);
    }

    private void doVisit(IgnoreUnless annotation, ISkippable skippable) {
        String[] tags = annotation.value();
        String targetTag = System.getenv("functional.tag");

        if (GroovyRuntimeUtil.isTruthy(targetTag)) {
            skippable.setSkipped(!tags.contains(targetTag));
        }
    }
}

@Retention(RetentionPolicy.RUNTIME)
@Target([ElementType.TYPE, ElementType.METHOD])
@ExtensionAnnotation(IgnoreUnlessExtension.class)
public @interface IgnoreUnless {
    String[] value() default [];
}

使用@IgnoreUnless注释我现在可以将类或方法标记为@IgnoreUnless(“tag1”)或@IgnoreUnless([“tag1”,“tag2”]),并且如果在运行命令上提供了标记,则测试将被跳过注释,并且在列表中没有提供标记。

1 个答案:

答案 0 :(得分:0)

要跳过具有注释的规范,您可以创建一个实现Spock的IAnnotationDrivenExtension的扩展。有关示例,请参见IgnoreExtension和IgnoreIfExtension。您的扩展程序可以获得&#34; functional.tag&#34; env var并在Tags annotation的值中搜索它。

如果您不介意使用多个注释,而不是参数化单个注释,那么您可以使用现有的扩展和配置执行您想要的操作,而不是创建自己的扩展。

但是,如果您想跳过具有单个参数化注释的规范,则需要实现IGlobalExtension。有关示例,请参阅IncludeExcludeExtension。您可以在jar中将全局扩展名作为服务发布,例如,使用Grails脚本,如下所示:

includeTargets << grailsScript('Init')
includeTargets << grailsScript('Compile')

target(buildAll: 'build the foo-spock-extensions.jar') {
    depends(compile, buildJar)
}

target(buildJar: 'build the foo-spock-extensions.jar') {
    def libDir = new File((File)grailsSettings.baseDir, 'lib')
    def jarFile = new File(libDir, 'foo-spock-extensions.jar')

    def serviceType = 'org.spockframework.runtime.extension.IGlobalExtension'
    ant.delete(quiet: true, file: jarFile)
    ant.jar( destfile: jarFile ) {
        fileset(dir: classesDirPath) {
            include(name: '**/*ExecuteWhenPropertySet*.class')  // 3 top classes + a couple closures
            include(name: '**/ReportConnectionLeaksExtension*.class')  // top class & nested Listener
        }
        // Generate the serviceType file in META-INF/services, to plugin to Spock's ExtensionClassesLoader.
        service(type: serviceType) {
            provider(classname: 'com.example.foo.testing.OnlyExecuteWhenPropertySetExtension')
            provider(classname: 'com.example.foo.testing.ReportConnectionLeaksExtension')
        }
    }
}


setDefaultTarget( buildAll )