Cucumber无法为Scenario Outline生成正确测试代码求助
问题:Cucumber Scenario Outline无法生成带参数的测试方法体
使用Cucumber编写测试用例时,Scenario Outline功能无法正常运行:生成的测试方法没有参数,.feature文件中的步骤始终被标记为未定义。普通Scenario可以正常生成并运行。
官方文档示例问题
按照Gherkin官方示例编写的Scenario Outline:
Scenario Outline: eating Given there are <start> cucumbers When I eat <eat> cucumbers Then I should have <left> cucumbers Examples: | start | eat | left | | 12 | 5 | 7 | | 20 | 5 | 15 |
Cucumber生成的代码无参数,且步骤未关联:
public class SomeFeature { @Given("there are <start> cucumbers") public void thereAreStartCucumbers() { } @When("I eat <eat> cucumbers") public void iEatEatCucumbers() { } @Then("I should have <left> cucumbers") public void iShouldHaveLeftCucumbers() { } }
自定义示例问题
自己编写的加法测试示例同样存在问题:
Feature: Test a numbers addition Scenario Outline: Java can add numbers properly When <add1> gets added to <add2> Then expect the result to be <sum> Examples: | add1 | add2 | sum | | 2 | 2 | 4 | | 4 | 5 | 9 |
对应的Step Definitions写法错误,导致无法匹配:
public class MyStepdefs { @When("<add{int}> gets added to <add{int}>") public void addGetsAddedToAdd(int arg0, int arg1) { } @Then("expect the result to be <sum>") public void expectTheResultToBeSum() { } }
当前pom.xml配置
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>au.com.dius.pact.provider</groupId> <artifactId>junit5spring</artifactId> <version>${pact.version}</version> </dependency> <dependency> <groupId>au.com.dius.pact.provider</groupId> <artifactId>junit5</artifactId> <version>${pact.version}</version> </dependency> <dependency> <groupId>au.com.dius.pact.consumer</groupId> <artifactId>junit5</artifactId> <version>${pact.version}</version> </dependency> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <!-- zum senden von Requests an den Mock-Server --> <artifactId>httpclient5</artifactId> <version>5.1.3</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>2.7.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>${logback.version}</version> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> <version>7.8.1</version> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-junit-platform-engine</artifactId> <version>7.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>4.4.0</version> <scope>test</scope> </dependency> <dependency> <groupId>com.github.tomakehurst</groupId> <artifactId>wiremock-jre8-standalone</artifactId> <version>2.31.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-suite</artifactId> <version>1.9.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>5.6.6</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>5.6.6</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit-platform</artifactId> <version>2.22.2</version> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-spring</artifactId> <version>7.2.3</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M4</version> <configuration> <properties> <configurationParameters> cucumber.junit-platform.naming-strategy=long </configurationParameters> </properties> <includes> <include>**/*Tests.java</include> <include>**/*TestRunner.java</include> <include>**/*MyStepDefs.java</include> </includes> </configuration> </plugin> <plugin> <groupId>au.com.dius.pact.provider</groupId> <artifactId>maven</artifactId> <version>${pact.version}</version> <configuration> <pactDirectory>${project.build.directory}/pacts</pactDirectory> <pactBrokerUrl>http://pact.datev.de</pactBrokerUrl> <projectVersion>${project.version}</projectVersion> <tags> <!--suppress UnresolvedMavenProperty --> <tag>${pact.tag}</tag> </tags> </configuration> </plugin> </plugins> </build>
排查与解决方法
1. 统一Cucumber依赖版本
pom.xml中cucumber-java版本为7.8.1,但cucumber-spring版本为7.2.3,版本不一致会导致功能兼容问题。将cucumber-spring版本修改为7.8.1,保持所有Cucumber相关依赖版本统一。
2. 修正Step Definitions的注解表达式
Scenario Outline中的<变量>是用来关联Examples表格的占位符,Step Definitions的注解需要用正则表达式匹配实际数据,而非直接引用<变量>:
- 官方示例修正后的Step Definitions:
public class SomeFeature { @Given("there are (\\d+) cucumbers") public void thereAreXCucumbers(int start) { // 实现逻辑 } @When("I eat (\\d+) cucumbers") public void iEatXCucumbers(int eat) { // 实现逻辑 } @Then("I should have (\\d+) cucumbers") public void iShouldHaveXCucumbers(int left) { // 实现逻辑 } }
- 自定义加法示例修正后的Step Definitions:
public class MyStepdefs { @When("(\\d+) gets added to (\\d+)") public void addGetsAddedToAdd(int add1, int add2) { // 实现逻辑 } @Then("expect the result to be (\\d+)") public void expectTheResultToBeSum(int sum) { // 实现逻辑 } }
解释:(\\d+)是正则表达式,用于匹配字符串中的整数,Cucumber会自动将捕获到的数值映射到方法的参数中。
3. 检查IDE自动生成逻辑
部分IDE自动生成Step Definitions时,会错误地将<变量>直接写入注解,此时需要手动修改正则表达式,替换为匹配实际数据的模式(如\\d+匹配整数,\\w+匹配字符串等)。
4. 验证测试扫描路径
确保Cucumber能扫描到Step Definitions类:在测试启动类中通过注解指定features文件路径和Step Definitions所在包:
import io.cucumber.junit.platform.engine.Cucumber; @Cucumber( features = "src/test/resources/features", glue = "com.yourpackage.stepdefs" // 替换为你的Step Definitions所在包路径 ) public class TestRunner { }
内容的提问来源于stack exchange,提问作者Daniel Kozak
相关产品推荐
相关产品推荐

