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

如何在Gherkin+Cucumber+Cypress中合理规划用户清理测试流程

FreeIPA WebUI测试场景重构问题及解决方案

问题背景

我正在为专注于用户操作的WebUI应用(FreeIPA)编写测试,需测试多用户添加及删除功能。由于本地开发时后端持续运行不重启,需确保清理前次测试残留的用户。现有测试代码如下:

Background:
    Given I am logged in as "admin"
    Given I am on "active-users" page

  Scenario Outline: Add a new user
    When I click on "Add" button
    * I type in the field "User login" text "<userLogin>"
    * I type in the field "First name" text "<firstName>"
    * I type in the field "Last name" text "<lastName>"
    * I type in the field "New Password" text "<password>"
    * I type in the field "Verify password" text "<password>"
    * in the modal dialog I click on "Add" button
    Then I should see "<userLogin>" entry in the data table
    Examples:
      | userLogin | firstName | lastName | password             |
      | testuser1 | Arthur    | Dent     | ILoveKlingonPoetry42 |
      | testuser2 | Banana    | Bread    | FishAndChips097      |
      | testuser3 | Cypress   | Gateway  | TestingIsFun73       |


  Scenario: Delete a user
    Given I should see "testuser1" entry in the data table
    When I select entry "testuser1" in the data table
    And I click on "Delete" button
    Then I see "Remove active users" modal

    When in the modal dialog I check "Delete" radio selector
    And in the modal dialog I click on "Delete" button
    Then I should not see "testuser1" entry in the data table

我尝试过三种方案但均存在问题:

  • 使用Before钩子:该钩子在Background前执行(管理员登录前),导致测试失败;
  • 在Background块中加入"清理状态"步骤:该步骤会在每个场景前执行,导致Delete a user场景失败;
  • 在Add a new user场景中添加"清理状态"步骤作为第一步:这会破坏多用户可见的测试目的。

请问应如何重构测试流程,让Add a new user场景从空用户表开始,同时保留添加的用户供Delete场景使用?若此方式违反耦合原则,是否可行在场景间复用场景?


解决方案

思路1:标签+针对性清理钩子(保留场景依赖)

通过给场景打标签,让清理逻辑只在指定场景前触发,既保证添加用户场景从空表启动,又不干扰删除场景依赖已添加的用户。

  1. 给添加用户场景添加标签:
@cleanup-before
Scenario Outline: Add a new user
    # 原有步骤不变
  1. 调整Before钩子逻辑,确保在Background之后执行清理(不同测试框架实现略有差异):
    • 如果框架支持钩子优先级,设置更高优先级让钩子在Background后运行:
      # 以Cucumber Ruby为例
      Before('@cleanup-before', :order => 2) do
        step("I delete all users with login starting with 'testuser'")
      end
      
    • 如果不支持优先级,改用API完成登录和清理(跳过WebUI操作,效率更高):
      Before('@cleanup-before') do
        # 调用后台API完成管理员认证
        api_login("admin", "admin-password")
        # 调用API批量删除测试用户
        api_delete_all_test_users
      end
      

思路2:独立场景设计(避免耦合,推荐)

场景间依赖会导致测试脆弱——一旦添加场景失败,删除场景也会跟着失效。更稳定的方案是让每个场景独立处理前置条件:

  1. 重构添加用户场景:
Scenario Outline: Add multiple users and verify presence
    Given I clean up all test users
    When I add a user with login "<userLogin>", first name "<firstName>", last name "<lastName>" and password "<password>"
    Then I should see "<userLogin>" entry in the data table
    Examples:
      | userLogin | firstName | lastName | password             |
      | testuser1 | Arthur    | Dent     | ILoveKlingonPoetry42 |
      | testuser2 | Banana    | Bread    | FishAndChips097      |
      | testuser3 | Cypress   | Gateway  | TestingIsFun73       |

这里把添加用户的重复步骤封装成复合步骤I add a user with...,简化场景结构。

  1. 重构删除用户场景:
Scenario: Delete an existing user
    Given I add a user with login "testuser1", first name "Arthur", last name "Dent" and password "ILoveKlingonPoetry42"
    And I should see "testuser1" entry in the data table
    When I select entry "testuser1" in the data table
    And I click on "Delete" button
    Then I see "Remove active users" modal

    When in the modal dialog I check "Delete" radio selector
    And in the modal dialog I click on "Delete" button
    Then I should not see "testuser1" entry in the data table

删除场景不再依赖其他场景,自行创建测试用户,测试独立性和稳定性大幅提升。

思路3:场景大纲复用逻辑(耦合性高,不推荐)

如果必须保留场景间关联,可以在Background中先批量添加用户,再执行删除场景,但这种方式耦合性强,容易引发连锁失败:

Background:
    Given I am logged in as "admin"
    Given I am on "active-users" page
    Given I clean up all test users
    And I add a user with login "testuser1", first name "Arthur", last name "Dent" and password "ILoveKlingonPoetry42"
    And I add a user with login "testuser2", first name "Banana", last name "Bread" and password "FishAndChips097"

Scenario: Delete testuser1
    Given I should see "testuser1" entry in the data table
    # 原有删除步骤

Scenario: Delete testuser2
    Given I should see "testuser2" entry in the data table
    # 原有删除步骤

总结

  • 若暂时需要保留场景依赖,优先用标签+针对性清理钩子的方案,满足需求的同时降低耦合;
  • 从长期测试稳定性考虑,强烈推荐独立场景设计,每个场景自行处理前置条件;
  • 场景间复用逻辑更适合通过封装复合步骤实现,而非直接依赖其他场景的执行结果。

内容的提问来源于stack exchange,提问作者Michal Polovka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:34:58