如何使用 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 用户,您有足够的能力来决定哪个选项最有意义。
在创建新场景时,我只想测试我当前使用的场景。为此,我想在我的场景之前使用 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 用户,您有足够的能力来决定哪个选项最有意义。