1. 引言

Cucumber行为驱动开发 (BDD) 中流行的工具,用于用自然语言编写测试场景。在Cucumber中使用参数可以实现动态和可复用的测试。

本文将探讨在Java测试中使用Cucumber参数的核心技术,帮你避开常见坑点。

2. 理解Cucumber参数

Cucumber参数是特性文件中的占位符,允许场景使用不同输入执行。

下面是一个字符串参数的基础示例:

Feature: 用户登录
  Scenario: 用户登录系统
    Given 用户输入用户名 "john_doe" 和密码 "password123"
    When 用户点击登录按钮
    Then 应显示仪表盘

步骤定义通过注解捕获这些参数:

public class LoginSteps {
    private static final Logger logger = LoggerFactory.getLogger(LoginSteps.class);

    @Given("用户输入用户名 {string} 和密码 {string}")
    public void enterUsernameAndPassword(String username, String password) {
        logger.info("用户名: {}, 密码: {}", username, password);
    }

    @When("用户点击登录按钮")
    public void clickLoginButton() {
        logger.info("登录按钮被点击");
    }

    @Then("应显示仪表盘")
    public void verifyDashboardDisplayed() {
        logger.info("仪表盘已显示");
    }
}

这里我们定义了与特性文件中每个步骤对应的步骤定义。**@Given、@When 和 @Then 注解 捕获场景中指定的参数,并将其传递给对应方法。**

3. 使用 DataTable 处理列表参数

DataTable 允许使用多组数据进行测试。

看个简单粗暴的示例:

Scenario: 验证多账户用户登录
  Given 用户尝试使用以下账户登录:
    | username    | password   |
    | john_doe    | password1  |
    | jane_smith  | password2  |
  When 每个用户尝试登录
  Then 每个用户应成功访问系统

我们用自定义对象列表处理 DataTable

public class DataTableLoginSteps {
    private static final Logger logger = LoggerFactory.getLogger(DataTableLoginSteps.class);

    @Given("用户尝试使用以下账户登录:")
    public void loginUser(List<UserCredentials> credentialsList) {
        for (UserCredentials credentials : credentialsList) {
            logger.info("用户名: {}, 密码: {}", credentials.getUsername(), credentials.getPassword());
        }
    }

    public static class UserCredentials {
        private String username;
        private String password;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }
}

本例中,我们使用 DataTable 将特性文件中的数据表映射为 UserCredentials 对象列表。这样就能遍历列表并单独处理每组凭据。

4. 使用正则表达式

正则表达式 (regex) 实现灵活的参数匹配。看个邮箱验证的示例:

Scenario: 验证邮箱有效性
  Given 用户输入邮箱地址 "test@example.com"
  When 用户提交注册表单
  Then 邮箱应成功通过验证

用步骤定义捕获邮箱参数:

public class RegexLoginSteps {
    private static final Logger logger = LoggerFactory.getLogger(RegexLoginSteps.class);

    @Given("用户输入邮箱地址 \"([^\"]*)\"")
    public void enterEmailAddress(String emailAddress) {
        logger.info("邮箱: {}", emailAddress);
    }
}

这里用正则表达式捕获邮箱参数。regex \"([^\"]*)\" 匹配双引号内的任意字符串,让我们能处理动态邮箱地址。

5. 使用自定义转换器

自定义转换器将输入字符串转为特定Java类型。看个日期转换的示例:

Scenario: 验证日期转换
  Given 用户输入出生日期 "1990-05-15"
  When 用户提交注册表单
  Then 出生日期应正确存储

定义步骤定义处理数据转换:

public class LocalDateTransformer {
    private static final Logger logger = LoggerFactory.getLogger(LocalDateTransformer.class);

    @ParameterType("yyyy-MM-dd")
    public LocalDate localdate(String dateString) {
        return LocalDate.parse(dateString);
    }

    @Given("用户输入出生日期 {localdate}")
    public void enterBirthdate(LocalDate birthdate) {
        logger.info("出生日期: {}", birthdate);
    }
}

这个方法中,我们用 @ParameterType 注解定义自定义转换器。转换器将 "yyyy-MM-dd" 格式的输入字符串转为 LocalDate 对象,让我们能在步骤定义中直接操作日期对象。

6. 总结

在Cucumber中传递列表参数能高效测试各种数据集。无论使用 DataTable、正则表达式还是自定义转换器,目标始终一致:简化测试流程并确保全面覆盖。

完整源码和示例见 GitHub仓库


原始标题:Passing List as Cucumber Parameter | Baeldung