问题描述
我可以通过以下方式对测试失败执行操作:
I can perform actions on test failure by using:
@After
public void afterTest(Scenario scenario) {
if (scenario.isFailed()) {
/*Do stuff*/
}
}
但是,我需要执行的一些操作取决于引发的异常以及引发的上下文.有没有办法让 Throwable 导致测试失败?例如,在 JUnit 中,我会通过扩展 TestWatcher 并在我的测试中添加一条规则来做到这一点:
However some of the actions I need to perform depend on the Exception that was thrown and in what context it was thrown. Is there a way to get the Throwable that caused the test to fail? For example in JUnit I would do this by extending TestWatcher and add a rule to my tests:
@Override
protected void failed(Throwable e, Description description) {
/*Do stuff with e*/
}
但是 cucumber-junit 实现不允许使用规则,因此该解决方案不适用于 Cucumber.
However the cucumber-junit iplementation does not allow the use of rules, so this solution would not work with Cucumber.
我认为我不需要解释为什么在测试失败时访问抛出的异常会有用,但是我仍然会提供一个示例:
I don't think I need to explain why accessing a thrown exception on test failure would be useful, however I will still provide an Example:
我的测试环境并不总是稳定的,所以我的测试可能随时意外失败(没有特定的地方可以尝试捕获异常,因为它可能随时发生).发生这种情况时,我需要重新安排测试以进行另一次尝试,并记录事件,以便我们可以获得有关环境不稳定性(何时、多频繁、多长时间等)的一些好的统计数据.
My test environment is not always stable, so my tests might fail unexpectedly at any moment (there's no specific place I can try to catch the exception since it could occur at any time). When this happens I need the test to reschedule for another attempt, and log the incident so that we can get some good statistical data on the environment instability (when, how frequent, how long etc.)
推荐答案
Frank Escobar 建议的解决问题:
The problem with the work around suggested by Frank Escobar:
通过使用反射进入框架内部,您依赖于实现细节.这是一种不好的做法,当框架更改其实现时,您的代码可能会中断,正如您将在 Cucumber v5.0.0 中观察到的那样.
By using reflection to reach into a frameworks internals you're depending on implementation details. This is a bad practice, when ever the framework changes its implementation your code may break as you will observe in Cucumber v5.0.0.
Cucumber 中的 Hooks 旨在在场景之前和之后操纵测试执行上下文.他们不会报告测试执行本身.报告是跨领域的关注点,最好使用插件系统进行管理.
Hooks in Cucumber are designed to manipulate the test execution context before and after a scenario. They're not made to report on the test execution itself. Reporting is cross cutting concern and best managed by using the plugin system.
例如:
package com.example;
import io.cucumber.plugin.ConcurrentEventListener;
import io.cucumber.plugin.event.EventPublisher;
import io.cucumber.plugin.event.Result;
import io.cucumber.plugin.event.Status;
import io.cucumber.plugin.event.TestCase;
import io.cucumber.plugin.event.TestCaseFinished;
public class MyTestListener implements ConcurrentEventListener {
@Override
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestCaseFinished.class, this::handleTestCaseFinished);
}
private void handleTestCaseFinished(TestCaseFinished event) {
TestCase testCase = event.getTestCase();
Result result = event.getResult();
Status status = result.getStatus();
Throwable error = result.getError();
String scenarioName = testCase.getName();
String id = "" + testCase.getUri() + testCase.getLine();
System.out.println("Testcase " + id + " - " + status.name());
}
}
使用 JUnit 4 和 TestNG 时,您可以使用以下方式激活此插件:
When using JUnit 4 and TestNG you can activate this plugin using:
@CucumberOptions(plugin="com.example.MyTestListener")
使用 JUnit 5,您可以将其添加到 junit-platform.properties
:
With JUnit 5 you add it to junit-platform.properties
:
cucumber.plugin=com.example.MyTestListener
或者如果您使用的是 CLI
Or if you are using the CLI
--plugin com.example.MyTestListener
这篇关于如何获取 Java 中 Cucumber 测试失败时引发的异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!