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

Cucumber BDD参数化报UndefinedStepException异常如何解决

Cucumber BDD参数化测试步骤未定义报错修复

问题现象

  • 测试执行时Chrome浏览器正常启动,目标登录页可正常加载
  • 运行到账号密码输入步骤时中断,抛出io.cucumber.junit.UndefinedStepException,提示User enters Sai and 12345等共2个步骤未定义

关联代码

TestRunner 测试运行器

package StepDefinitions; 
import io.cucumber.junit.Cucumber; 
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;

@RunWith(Cucumber.class) 
@CucumberOptions(
    features="src/test/resources/Features", 
    glue={"StepDefinitions"}, 
    monochrome=true
)
public class TestRunner {}

LoginDemoSteps 步骤定义类

package StepDefinitions;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.cucumber.java.en.*;

public class LoginDemoSteps {
    WebDriver driver = null;

    @Given("browser is open")
    public void browser_is_open() {
        System.setProperty("webdriver.chrome.driver",System.getProperty("user.dir")+"\\src\\test\\resources\\drivers\\chromedriver.exe");
        driver=new ChromeDriver();
        driver.manage().window().maximize();
    }

    @And("user is on login page")
    public void user_is_on_login_page() {
        driver.get("https://example.testproject.io/web/");
    }

    @When("^User enters (.*) and (.*) $")
    public void User_enters_username_and_password(String username, String password) throws InterruptedException {
        driver.findElement(By.id("name")).sendKeys(username);
        driver.findElement(By.id("password")).sendKeys(password);
        Thread.sleep(3000);
    }
}

登录场景feature文件

Feature: Test login functionality

  Scenario Outline: Check login is successful with valid credentials
    Given browser is open
    And user is on login page
    When User enters <username> and <password>

    Examples: 
      | username | password |
      | Sai      |    12345 |
      | Ele      |    12345 |

根因分析

Cucumber步骤匹配要求步骤定义的表达式和feature文件中的步骤文本完全精确匹配,多/少空格、参数类型不匹配都会导致匹配失败,本次报错的两个触发点:

  1. 步骤注解的正则表达式末尾存在冗余空格:@When里写的正则是^User enters (.*) and (.*) $,结尾定位符$前多了一个空格,要求匹配的步骤文本末尾必须带空格,但feature文件中的对应步骤末尾无空格,直接导致匹配失效
  2. 正则使用(.*)通配符未做类型约束,对于数字格式的密码12345,Cucumber默认优先匹配精度更高的整数类型规则,因此报错给出的待实现片段将第二个参数识别为{int}类型,和现有方法的String类型参数不匹配

修复方法

修改步骤定义的@When注解即可,两种方案均有效:

方案1:修正原有正则

删除正则末尾的冗余空格,增加非贪婪匹配限定避免参数越界,修改后代码:

@When("^User enters (.*?) and (.*?)$")
public void user_enters_username_and_password(String username, String password) throws InterruptedException {
    driver.findElement(By.id("name")).sendKeys(username);
    driver.findElement(By.id("password")).sendKeys(password);
    Thread.sleep(3000);
}

注:方法名首字母建议改为小写,符合Java编码规范,不影响运行但可提升代码可读性

方案2:使用Cucumber表达式替代正则(推荐,维护成本更低)

不需要写正则首尾定位符,直接用官方提供的参数占位符,不需要手动处理空格问题:

@When("User enters {string} and {string}")
public void user_enters_username_and_password(String username, String password) throws InterruptedException {
    driver.findElement(By.id("name")).sendKeys(username);
    driver.findElement(By.id("password")).sendKeys(password);
    Thread.sleep(3000);
}

注:{string}占位符可兼容字符串、数字格式的账号密码,不需要单独区分参数类型,比正则写法更不容易出错

验证

修改后重新运行测试类,步骤可正常匹配,浏览器会自动填入Examples中配置的两组测试凭据,不再抛出步骤未定义异常。

内容的提问来源于stack exchange,提问作者Jackie M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:27:25