Cucumber-JVM是否支持通过步骤名称调用步骤实现软执行?
问题
之前在Stack Overflow上了解到,cuke4duke可以通过继承Steps类在步骤定义中调用其他步骤,示例代码如下:
// 在Java中调用步骤定义内的步骤,需继承cuke4duke.Steps import cuke4duke.StepMother; import cuke4duke.Steps; import cuke4duke.annotation.I18n.EN.When; public class CallingSteps extends Steps { public CallingSteps(StepMother stepMother) { super(stepMother); } @When("^I call another step$") public void iCallAnotherStep() { Given("it is magic"); // 调用其他地方定义的步骤 } }
但cuke4duke已经废弃12年,Cucumber-JVM是它的继任者,想请教:Cucumber-JVM是否支持类似通过步骤名称在步骤定义中调用其他步骤的功能?
另外希望实现一个通用的Kotlin方法,传入步骤名称就能调用对应步骤,在try-catch块中执行并记录异常,让这个步骤成为不会导致场景失败的「软执行」版本,而且新增步骤时不需要更新这个方法,预期代码示例如下:
@When("soft call the step {string}") fun softCall(stepToCall: String) { runCatching { Given(stepToCall) // 调用其他地方定义的步骤 }.onFailure { // 记录异常 } }
回答
Cucumber-JVM确实支持在步骤定义中调用其他步骤,但和cuke4duke的实现方式不同,不需要继承特定类,可通过Cucumber提供的API动态查找并执行步骤。
通用软调用步骤的Kotlin实现方案
要实现你想要的「软执行」逻辑,无需为新增步骤修改方法,可以借助Cucumber的StepDefinitionRegistry和StepExpressionFactory来动态匹配并调用步骤,代码如下:
import io.cucumber.java.en.When import io.cucumber.core.api.Scenario import io.cucumber.core.stepexpression.StepExpressionFactory import io.cucumber.core.registry.StepDefinitionRegistry import java.util.Locale import javax.inject.Inject class SoftStepCaller { @Inject private lateinit var stepDefinitionRegistry: StepDefinitionRegistry @Inject private lateinit var locale: Locale @When("soft call the step {string}") fun softCall(stepToCall: String, scenario: Scenario) { runCatching { // 根据步骤文本创建表达式,用于匹配已定义的步骤 val stepExpression = StepExpressionFactory(locale).createExpression(stepToCall) // 查找匹配的步骤定义 val match = stepDefinitionRegistry.lookupStepDefinition(stepExpression) ?: throw IllegalArgumentException("找不到匹配的步骤:$stepToCall") // 执行找到的步骤 match.execute(scenario) }.onFailure { exception -> // 记录异常,可写入场景报告或日志 scenario.write("软执行步骤失败:${exception.message}") scenario.embed(exception.stackTraceToString().toByteArray(), "text/plain") } } }
关键说明
- 动态匹配步骤:通过
StepDefinitionRegistry和StepExpressionFactory,能根据传入的步骤文本自动匹配已注册的步骤,新增步骤时无需修改该方法。 - 软执行逻辑:用
runCatching捕获所有异常,执行失败仅记录信息,不会中断整个场景。 - 依赖注入:Cucumber-JVM会自动注入
StepDefinitionRegistry和Locale,无需手动初始化,确保能获取所有已定义的步骤。
注意事项
- 传入的步骤文本需要和原步骤定义的表达式完全匹配,包括参数内容。比如原步骤是
Given "I have {int} apples",传入的文本需是"I have 5 apples"这类完整格式。 - 若步骤包含参数,要确保传入文本的参数格式正确,否则会匹配失败或执行出错。
内容的提问来源于stack exchange,提问作者Bar_g5
相关产品推荐
相关产品推荐

