如何使用 Serenity、JBehave 和 Selenium 设置配置的嵌入器以使用元过滤器 (-skip)

How to set up a configured embedder for use of meta filters (-skip) with Serenity, JBehave and Selenium

在创建新场景时,我只想测试我当前使用的场景。为此,我想在我的场景之前使用 Meta: @skip 标签。正如我发现我必须使用 embedder 来配置使用的元标记,所以我尝试了:

configuredEmbedder().useMetaFilters(Arrays.asList("-skip"));

但实际上这对我的测试场景仍然没有影响。我在 SerenityStories 测试套件定义的构造函数中使用了它。这是 class:

的完整代码
public class AcceptanceTestSuite extends SerenityStories {
    @Managed
    WebDriver driver;

    public AcceptanceTestSuite() {
    System.setProperty("webdriver.chrome.driver", "D:/files/chromedriver/chromedriver.exe");
    System.setProperty("chrome.switches", "--lang=en");
    System.setProperty("restart.browser.each.scenario", "true");
    configuredEmbedder().useMetaFilters(Arrays.asList("-skip"));

    runSerenity().withDriver("chrome"); 
    }

    @Override
    public Configuration configuration() {
    Configuration configuration = super.configuration();

    Keywords keywords = new LocalizedKeywords(DEFAULTSTORYLANGUAGE);
    Properties properties = configuration.storyReporterBuilder().viewResources();
    properties.setProperty("encoding", "UTF-8");

    configuration.useKeywords(keywords)
            .useStoryParser(new RegexStoryParser(keywords, new ExamplesTableFactory(new LoadFromClasspath(this.getClass()))))
            .useStoryLoader(new UTF8StoryLoader()).useStepCollector(new MarkUnmatchedStepsAsPending(keywords))
            .useDefaultStoryReporter(new ConsoleOutput(keywords)).storyReporterBuilder().withKeywords(keywords).withViewResources(properties);


    return configuration;
    }
}

这是错误的地方还是我错过了什么?仍然执行所有场景。

编辑:

我在 classes 之后进行了更改,现在我认为它 "works"

public AcceptanceTestSuite() {
    System.setProperty("webdriver.chrome.driver", "D:/files/chromedriver/chromedriver.exe");
    System.setProperty("chrome.switches", "--lang=de");
    System.setProperty("restart.browser.each.scenario", "true");
    this.useEmbedder(configuredEmbedder());

    runSerenity().withDriver("chrome"); 
}

@Override
public Embedder configuredEmbedder() {
    final Embedder embedder = new Embedder();
    embedder.embedderControls()
        .useThreads(1)
        .doGenerateViewAfterStories(true)
        .doIgnoreFailureInStories(false)
        .doIgnoreFailureInView(false)
        .doVerboseFailures(true);

    final Configuration configuration = configuration();

    embedder.useConfiguration(configuration);
    embedder.useStepsFactory(stepsFactory());
    embedder.useMetaFilters(Arrays.asList("-skip"));

    return embedder;
}

但现在我收到消息 [pool-1-thread-1] INFO net.serenitybdd.core.Serenity - TEST IGNORED 但场景仍在执行。仅在结果页面中,我得到该场景被忽略(但仍被执行)的信息。有没有办法跳过这个场景,这样它就不会 运行?

我无法使用 configuredEmbedder() 实现 运行,但通过在我的 mvn 运行 配置中添加 -Dmetafilter="+working -finished" 作为目标并使用标签 @working对于我正在使用的场景以及我想要 运行 和 @finsihed 对于我不想执行的场景。如果我想更改元标记,我仍然必须更改 运行 配置,所以它不是很舒服,但我仍然得到了我想要的东西。

调查

我调试了 serenity-jbehave classes,试图理解为什么设置

configuredEmbedder().useMetaFilters(Collections.singletonList("-skip"))

没有在所有可能的地方工作我把它放在我的 class 扩展 SerenityStories 中,我找到了 ExtendedEmbedder#embedder 中的 metaFilters 的战略代码位置用我们在 class 中定义的内容覆盖到 serenity-jbehave.

的设置中

这个方法是SerenityReportingRunner#createPerformableTree:

private PerformableTree createPerformableTree(List<CandidateSteps> candidateSteps, List<String> storyPaths) {
    ExtendedEmbedder configuredEmbedder = this.getConfiguredEmbedder();
    configuredEmbedder.useMetaFilters(getMetaFilters());
    BatchFailures failures = new BatchFailures(configuredEmbedder.embedderControls().verboseFailures());
    PerformableTree performableTree = configuredEmbedder.performableTree();
    RunContext context = performableTree.newRunContext(getConfiguration(), candidateSteps,
            configuredEmbedder.embedderMonitor(), configuredEmbedder.metaFilter(), failures);
    performableTree.addStories(context, configuredEmbedder.storyManager().storiesOfPaths(storyPaths));
    return performableTree;
}

这一行改变集合metaFilters:

    configuredEmbedder.useMetaFilters(getMetaFilters());

它会覆盖当前的 metaFilters 值。

进一步调用链,我们得到定义它从何处获取的逻辑 metaFilters,即我们可以实际设置它的地方。

SerenityReportingRunner#createPerformableTree

SerenityReportingRunner#getMetaFilters

SerenityReportingRunner#getMetafilterSetting

这就是我们需要的方法!

private String getMetafilterSetting() {
    Optional<String> environmentMetafilters = getEnvironmentMetafilters();
    Optional<String> annotatedMetafilters = getAnnotatedMetafilters(testClass);
    Optional<String> thucAnnotatedMetafilters = getThucAnnotatedMetafilters(testClass);
    return environmentMetafilters.orElse(annotatedMetafilters.orElse(thucAnnotatedMetafilters.orElse("")));
}

正如我们在这里看到的,metaFilters 可以在三个地方定义,并且它们相互覆盖。按照优先级降低顺序,它们是:

  • metafilter 的值(完全小写!)VM 属性.
  • 我们 SerenityStories class 上 net.serenitybdd.jbehave.annotations.Metafilter 注释的值。
  • 我们 SerenityStories class 上 net.thucydides.jbehave.annotations.Metafilter 注释的值。此注释已弃用,但为 backwards-compatibility.
  • 保留

适用于当前 serenity-jbehave 版本的解决方案

我已经 tried/debugged 所有这三个选项,它们可以工作并相互覆盖,如上所述。

1。使用环境metafilter属性

将此添加到我的 JVM 运行 参数:

-Dmetafilter=skip

2。使用现代 @Metafilter 注释

import net.serenitybdd.jbehave.SerenityStories;
import net.serenitybdd.jbehave.annotations.Metafilter;

@Metafilter("-skip")
public class Acceptance extends SerenityStories {

3。使用已弃用的 @Metafilter 注释

import net.serenitybdd.jbehave.SerenityStories;
import net.thucydides.jbehave.annotations.Metafilter;

@Metafilter("-skip") // warned as deprecated
public class Acceptance extends SerenityStories {

我当前项目的解决方案是在我的测试 class 中使用当前 @Metafilter("-skip") 注释,而不是依赖 on/have 来更改特定 Jenkins/local 的 VM 属性开发执行。

可能提出的拉取请求

https://github.com/serenity-bdd/serenity-core/issues/95 — 这里 Serenity 的人建议我用这个修复做一个 PR,因为他们现在不专注于 Serenity + JBehave。

我知道在哪里进行更改(在上述代码链中),但我不知道应该是什么压倒一切的逻辑:

— 来自 configuredEmbedder 的 MetaFilters 覆盖任何 ENV/annotation MetaFilters。

— 任何 ENV/annotation 元过滤器覆盖来自 configuredEmbedder

的元过滤器

— 来自 configuredEmbedder 的 MetaFilters 与 ENV/annotation MetaFilters 合并。此选项需要合并优先级。

有什么建议吗?

在任何类型的修复中,我更愿意添加关于覆盖现在如何工作的显式日志 SerenityReportingRunner#getMetafilterSetting,因为当前行为实际上是 non-obvious 并且花了很多时间来调查.

只要您记录得很好(https://github.com/serenity-bdd/the-serenity-book 中的某些文档会很棒),我认为作为 JBehave/Serenity 用户,您有足够的能力来决定哪个选项最有意义。