原文地址:Frontend Testing Guide: 10 Essential Rules for Naming Tests
更好的测试之路始于一些非常简单的事情:如何命名测试。好的测试名称:
- 使您的测试套件更易于维护
- 指导您编写关注用户行为的测试
- 提高团队的清晰度和可读性
在这篇博文中,我们将探讨编写更好的测试的 10 条基本规则,这些规则将改变您的测试方法。这些原则是:
- 与框架无关
- 适用于整个测试金字塔
- 适用于各种测试工具:
- 单元测试(Jest、Vitest)
- 集成测试
- 端到端测试(Cypress、Playwright)
通过遵循这些规则,无论您选择什么测试框架或方法,您都将创建更强大且更易于理解的测试套件。
1. 使用使用 'shoule' + 动词
每个测试名称都应以“should”开头,后跟一个动作动词。
it('displays the error message', () => {})
it('modal visibility', () => {})
it('form validation working', () => {})
it('should displays the error message when validation fails', () => {})
it('should show modal when trigger button is clicked', () => {})
it('should validate form when user submits', () => {})
通用模式:should 动词 额外说明
2. 包含触发事件
指定导致您正在测试的行为的原因。
it('should update counter', () => {})
it('should validate email', () => {})
it('should show dropdown', () => {})
it('should increment counter when plus button is clicked', () => {})
it('should show error when email format is invalid', () => {})
it('should open dropdown when toggle is clicked', () => {})
通用模式:should 动词 额外说明 when 操作事件
3. 使用描述性上下文对相关测试进行分组
使用描述块创建清晰的测试层次结构。
describe('AuthForm', () => {
it('should test empty state', () => {})
it('should test invalid state', () => {})
it('should test success state', () => {})
})
describe('AuthForm', () => {
describe('when form is empty', () => {
it('should disable submit button', () => {})
it('should not show any validation errors', () => {})
})
describe('when submitting invalid data', () => {
it('should show validation errors', () => {})
it('should keep submit button disabled', () => {})
})
})
通用模式:
describe('[Component/Feature]', () => {
describe('when [specific condition]', () => {
it('should [expected behavior]', () => {})
})
})
4. 明确命名状态更改
在测试名称中清楚地描述之前和之后的状态。
it('should change status', () => {})
it('should update todo', () => {})
it('should modify permissions', () => {})
it('should change status from pending to approved', () => {})
it('should mark todo as completed when checkbox clicked', () => {})
it('should upgrade user from basic to premium', () => {})
通用模式: should change [属性-attribute] from [初始状态] to [结束状态]
5. 清楚地描述异步行为
包括异步操作的加载和结果状态。
it('should load data', () => {})
it('should handle API call', () => {})
it('should fetch user', () => {})
it('should show skeleton while loading data', () => {})
it('should display error message when API call fails', () => {})
it('should render profile after user data loads', () => {})
通用模式: should [verb] [expected outcome] [during/after] [async operation]
6. 命名中明确错误案例
明确错误的类型及其原因
it('should show error', () => {})
it('should handle invalid input', () => {})
it('should validate form', () => {})
it('should show "Invalid Card" when card number is wrong', () => {})
it('should display "Required" when password is empty', () => {})
it('should show network error when API is unreachable', () => {})
通用模式: should show [specific error message] when [error condition]
7:使用商业语言,而不是技术术语
使用领域语言而不是实现细节编写测试。
it('should update state', () => {})
it('should dispatch action', () => {})
it('should modify DOM', () => {})
it('should save customer order', () => {})
it('should update cart total', () => {})
it('should mark order as delivered', () => {})
通用模式: should [business action] [business entity]
8:包括重要的先决条件
指定影响正在测试的行为的条件。
it('should enable button', () => {})
it('should show message', () => {})
it('should apply discount', () => {})
it('should enable checkout when cart has items', () => {})
it('should show free shipping when total exceeds $100', () => {})
it('should apply discount when user is premium member', () => {})
通用模式: should [expected behavior] when [precondition]
9:从用户角度命名 UI 反馈测试
描述用户感知到的视觉变化。
it('should set error class', () => {})
it('should toggle visibility', () => {})
it('should update styles', () => {})
it('should highlight search box in red when empty', () => {})
it('should show green checkmark when password is strong', () => {})
it('should disable submit button while processing', () => {})
通用模式: should [visual change] when [user action/condition]
10:逐步构建复杂的工作流程
将复杂的流程分解为清晰的步骤。
describe('Checkout', () => {
it('should process checkout', () => {})
it('should handle shipping', () => {})
it('should complete order', () => {})
})
describe('Checkout Process', () => {
it('should first validate items are in stock', () => {})
it('should then collect shipping address', () => {})
it('should finally process payment', () => {})
describe('after successful payment', () => {
it('should display order confirmation', () => {})
it('should send confirmation email', () => {})
})
})
通用模式:
describe('[Complex Process]', () => {
it('should first [initial step]', () => {})
it('should then [next step]', () => {})
it('should finally [final step]', () => {})
describe('after [key milestone]', () => {
it('should [follow-up action]', () => {})
})
})
完整示例
这是一个综合示例,展示了如何组合所有这些规则:
describe('ShoppingCart', () => {
it('test adding item', () => {})
it('check total', () => {})
it('handle checkout', () => {})
})
describe('ShoppingCart', () => {
describe('when adding items', () => {
it('should add item to cart when add button is clicked', () => {})
it('should update total price immediately', () => {})
it('should show item count badge', () => {})
})
describe('when cart is empty', () => {
it('should display empty cart message', () => {})
it('should disable checkout button', () => {})
})
describe('during checkout process', () => {
it('should validate stock before proceeding', () => {})
it('should show loading indicator while processing payment', () => {})
it('should display success message after completion', () => {})
})
})
测试名称清单
在提交测试之前,请验证其名称:
- 以 "should" 开头
- 使用明确的动作动词
- 指定触发条件
- 使用商务语言
- 描述可见的行为
- 足够具体以供调试
- 与相关测试进行逻辑分组
结论
深思熟虑的测试命名是编写更好测试的更广泛领域的基本组成部分。为了保持整个团队的一致性:
- 详细记录您的命名约定
- 与所有团队成员分享这些准则
- 将指南集成到您的开发工作流程中
对于使用 GitHub Copilot 等 AI 工具的团队:
- 将这些指南纳入您的项目文档中
- 将包含这些规则的 markdown 文件链接到 Copilot
- 这种集成允许 Copilot 建议符合您约定的测试名称
有关将文档链接到 Copilot 的更多信息,请参阅: VS Code 实验增强了 AI Copilot 功能
通过执行这些步骤,您可以确保整个项目的测试命名保持一致、高质量。
评论区
评论加载中...