如何在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:标签+针对性清理钩子(保留场景依赖)
通过给场景打标签,让清理逻辑只在指定场景前触发,既保证添加用户场景从空表启动,又不干扰删除场景依赖已添加的用户。
- 给添加用户场景添加标签:
@cleanup-before Scenario Outline: Add a new user # 原有步骤不变
- 调整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
- 如果框架支持钩子优先级,设置更高优先级让钩子在Background后运行:
思路2:独立场景设计(避免耦合,推荐)
场景间依赖会导致测试脆弱——一旦添加场景失败,删除场景也会跟着失效。更稳定的方案是让每个场景独立处理前置条件:
- 重构添加用户场景:
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...,简化场景结构。
- 重构删除用户场景:
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
相关产品推荐
相关产品推荐

