You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 01:50:30