【问题标题】:Tag Geb classes/tests for exclusion标记 Geb 类/测试以排除
【发布时间】:2015-03-18 16:15:09
【问题描述】:

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

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

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

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

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

编辑:

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

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"]),并且如果在运行命令上提供了一个标记,则测试已注释且列表中没有提供的标签的将被跳过。

【问题讨论】:

    标签: grails spock geb


    【解决方案1】:

    要跳过带有注释的规范,您可以创建一个实现 Spock 的 IAnnotationDrivenExtension 的扩展。有关示例,请参阅 IgnoreExtension 和 IgnoreIfExtension。您的扩展程序可以获取“functional.tag”环境变量并在您的标签注释的值中搜索它。

    如果您不介意使用多个注解,而不是参数化单个注解,那么您可以使用现有的扩展和配置来做您想做的事情,而不是创建自己的扩展。

    但是,如果您想跳过 没有 具有单个参数化注释的规范,则需要实现 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 )
    

    【讨论】:

    • 我能够使用 J. David Beutel 的指导来实现我的目标。按照他对“IgnoreIfExtension”的指导,我能够按照这种模式实现两个类,这允许我有条件地跳过没有预期标签的测试。我将用我到达的课程更新原始问题。
    • 感谢您的反馈,并发布您的解决方案!看起来您也可以删除 DELEGATE 和 JAVA_VERSION,因为您没有使用 IgnoreIfExtension 的 evaluateCondition()。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多