Cucumber案例

wen java案例 3

本文目录导读:

Cucumber案例

  1. 第一部分:案例背景与需求
  2. 第二部分:项目结构
  3. 第三部分:核心代码与脚本
  4. 第四部分:Cucumber 的核心机制(通俗版解释)
  5. 第五部分:优质案例的标准(避坑指南)

Cucumber案例通常指的是使用 Cucumber(一个基于BDD,即行为驱动开发的测试工具)来编写和执行的测试场景。

我将为你提供一个完整的实战案例,涵盖从需求到自动化脚本的完整流程。

为了让案例更直观,我将使用登录功能(最常见的业务场景)作为例子,并选择 Java + Selenium + Maven 作为技术栈(这是目前最主流的配置)。


第一部分:案例背景与需求

需求描述: 用户登录系统。

业务规则:

  1. 用户名和密码正确,登录成功,跳转到首页。
  2. 用户名正确,密码错误,提示“密码错误”。
  3. 用户名不存在,提示“用户不存在”。
  4. 用户名为空或密码为空,提示“用户名或密码不能为空”。

第二部分:项目结构

你需要创建如下标准的Maven项目结构:

src
├── main
│   └── java
└── test
    ├── java
    │   └── stepdefs          // 存放Step Definitions(步骤定义)
    │       └── LoginSteps.java
    │   └── runners           // 存放测试运行器
    │       └── TestRunner.java
    └── resources
        └── features          // 存放.feature文件
            └── login.feature

第三部分:核心代码与脚本

编写 Feature 文件(业务需求层)

文件路径: src/test/resources/features/login.feature

# 语言声明,如果使用中文,需要开启(我这里使用英文避免编码问题)
Feature: User Login
  As a registered user
  I want to log into the system
  So that I can access my dashboard
  Background:  # 前置条件:打开浏览器
    Given I am on the login page
  # --- 场景1:正常登录 ---
  Scenario Outline: Successful login with valid credentials
    When I enter username "<username>" and password "<password>"
    And I click the Sign in button
    Then I should see the dashboard page
    Examples:
      | username | password |
      | admin    | admin123 |
      | guest    | guest123 |
  # --- 场景2:密码错误 ---
  Scenario: Login fails with wrong password
    When I enter username "admin" and password "wrongpass"
    And I click the Sign in button
    Then I should see an error message "Password is incorrect"
  # --- 场景3:用户不存在 ---
  Scenario: Login fails with unregistered user
    When I enter username "unknown" and password "pass123"
    And I click the Sign in button
    Then I should see an error message "User does not exist"
  # --- 场景4:数据校验 ---
  Scenario: Login validation for empty fields
    When I enter username "" and password ""
    And I click the Sign in button
    Then I should see a validation message "Username and password cannot be empty"

编写 Step Definitions(步骤实现层)

文件路径: src/test/java/stepdefs/LoginSteps.java

这个类负责将 feature 文件中的自然语言翻译成可执行的代码。

package stepdefs;
import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class LoginSteps {
    private WebDriver driver;
    @Given("I am on the login page")
    public void i_am_on_login_page() {
        System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
        driver = new ChromeDriver();
        driver.get("http://example.com/login"); // 假设的登录页面
    }
    @When("I enter username {string} and password {string}")
    public void i_enter_username_and_password(String username, String password) {
        // 定位元素并输入
        driver.findElement(By.id("username")).sendKeys(username);
        driver.findElement(By.id("password")).sendKeys(password);
    }
    @And("I click the Sign in button")
    public void i_click_signin_button() {
        driver.findElement(By.id("submit")).click();
    }
    @Then("I should see the dashboard page")
    public void i_should_see_dashboard() {
        // 断言:当前URL发生变化 或者 存在某个“欢迎”元素
        Assert.assertTrue(driver.getCurrentUrl().contains("/dashboard"));
        driver.quit();
    }
    @Then("I should see an error message {string}")
    public void i_should_see_error_message(String expectedMessage) {
        // 断言页面提示
        String actualMessage = driver.findElement(By.cssSelector(".alert.error")).getText();
        Assert.assertEquals(expectedMessage, actualMessage);
        driver.quit();
    }
    @Then("I should see a validation message {string}")
    public void i_should_see_validation_message(String expectedMessage) {
        // 处理空值校验
        String actualMessage = driver.findElement(By.cssSelector(".alert.warning")).getText();
        Assert.assertEquals(expectedMessage, actualMessage);
        driver.quit();
    }
}

编写 Test Runner(测试执行层)

文件路径: src/test/java/runners/TestRunner.java

package runners;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(
        features = "src/test/resources/features",  // 指定Feature文件路径
        glue = "stepdefs",                        // 指定StepDefinitions路径
        plugin = {"pretty", "html:target/cucumber-reports"}, // 报告输出格式
        monochrome = true
)
public class TestRunner {
    // 无需额外代码
}

第四部分:Cucumber 的核心机制(通俗版解释)

面的案例为例,整个运行过程是“三个角色”的配合:

  1. 产品负责人/业务专家:编写 login.feature 文件(描述“做什么”)。
  2. 测试开发工程师:编写 LoginSteps.java(解决“怎么做”)。
  3. Cucumber 引擎:通过正则表达式匹配 feature 中的文字与 Steps 中的注解(如 @Given, @When),实现自动调用。

第五部分:优质案例的标准(避坑指南)

在做Cucumber案例时,下面几点非常重要:

  1. Step 复用的颗粒度:不要将所有的操作写在一个巨大的 Step 里,比如把 打开页面 提取出来,让所有场景共用(案例中的 Background)。
  2. 不能有 if 分支在 Steps 中:在 Steps 代码中,尽量避免复杂的 if/else 逻辑,断言应该放在 Then 里。
  3. 数据分离:尽量不要把测试数据硬编码在 Steps 代码中,要么写在 Examples 表格里(如案例中的 Scenario Outline),要么写在配置文件里。

上面的案例展示了 Cucumber 的一个完整生命周期: 从业务话术(Feature文件) -> 自动化步骤(Steps定义) -> 执行与断言

如果你需要针对特定场景(比如需要处理API接口测试数据库回滚异步请求)的案例,可以告诉我具体的业务细节,我可以帮你调整脚本。

上一篇Java契约测试案例

下一篇BDD案例

抱歉,评论功能暂时关闭!