如何让@manual标记场景显示在Serenity报告且不触发步骤定义错误
解决带@manual标签的Cucumber场景在Serenity BDD报告中显示且不触发UndefinedStepException的方案
要实现带@manual标签的Cucumber场景正常出现在Serenity报告中,同时避免因无步骤定义抛出io.cucumber.junit.UndefinedStepException,可以通过以下方式处理:
核心思路
让Serenity BDD接管手动测试场景的结果记录,同时拦截Cucumber对这类场景的步骤执行,避免未定义步骤报错。
1. 配置Serenity识别手动测试标签
在serenity.properties配置文件中添加以下配置,让Serenity将@manual标签标记为手动测试场景:
serenity.manual.test.tag=manual
这样Serenity会自动识别带该标签的场景,并在报告中归类为手动测试。
2. 添加Cucumber钩子拦截手动场景执行
编写一个Cucumber钩子类,拦截带@manual标签的场景,直接根据你定义的元数据(如@manual-result:passed)设置测试结果,并跳过后续步骤执行:
import io.cucumber.java.Before; import io.cucumber.java.Scenario; import io.cucumber.java.ScenarioScopedException; import net.serenitybdd.core.Serenity; import net.thucydides.core.model.TestResult; import java.util.Optional; public class ManualTestHook { @Before("@manual") public void processManualScenario(Scenario scenario) { // 提取手动测试结果标签值 Optional<String> manualResult = scenario.getSourceTagNames().stream() .filter(tag -> tag.startsWith("@manual-result:")) .map(tag -> tag.split(":", 2)[1]) .findFirst(); // 设置测试结果并记录报告数据 TestResult result = manualResult.map(res -> { if ("failed".equalsIgnoreCase(res)) { Serenity.recordReportData().withTitle("手动测试结果").andContents("标记为失败"); return TestResult.FAILED; } else { Serenity.recordReportData().withTitle("手动测试结果").andContents("标记为通过"); return TestResult.PASSED; } }).orElse(TestResult.PASSED); // 更新Serenity测试结果 Serenity.getCurrentSession().getCurrentTestOutcome().ifPresent(outcome -> outcome.setStatus(result)); // 抛出场景范围异常,跳过后续步骤执行 throw new ScenarioScopedException("跳过手动测试场景执行"); } }
这个钩子会在带@manual的场景执行前触发,设置好结果后直接终止场景的步骤执行,从而避免Cucumber去查找未定义的步骤。
3. 验证示例场景的处理效果
对于你的示例场景:
@JIRA_BOND_007 @manual @manual-result:passed @manual-last-tested:sprint-1 @manual-test-evidence:https://some.external/link.png Scenario: Dont want Manual steps to cause step definition failure Given John Ferguson Smart releases a new version of serenity bdd When tester marks a test as manual Then runner should not fail because of error "io.cucumber.junit.UndefinedStepException:"
- Serenity会在报告中显示该场景的所有元数据(JIRA编号、测试结果、最后测试版本、证据链接)
- 钩子会拦截场景执行,不会触发未定义步骤的异常
- 场景会以你指定的
passed状态出现在报告中
为什么之前会报错?
Cucumber默认会尝试执行所有场景的步骤,无论是否带有特殊标签。如果场景中的步骤没有对应的步骤定义,就会抛出UndefinedStepException。通过上述钩子拦截手动场景的执行,就彻底避免了这个问题。
内容的提问来源于stack exchange,提问作者Tomaso G
相关产品推荐
相关产品推荐

