* [misc] Refine unit test guide with clarified concepts and 5-step requirement
- Add core concept clarification section distinguishing Test Case vs Test Step - Correct terminology throughout document: script = test case, r()...e() = test step - Add mandatory 5-step requirement in warning, workflow, templates, and checklist - Update templates to show 5 test steps with proper naming convention - Enhance best practices section with test case/step organization principles - Improve quality checklist with accurate terminology and requirements 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+54
-21
@@ -9,6 +9,7 @@
|
||||
|
||||
**在开始编写任何代码之前,必须先创建测试分支!**
|
||||
**任何直接在开发分支上编写单元测试的行为都是严重违规!**
|
||||
**每个测试用例必须包含至少5个测试步骤(r()...e()语句)!**
|
||||
**必须严格按照分支→开发→测试→提交→推送的流程执行!**
|
||||
|
||||
---
|
||||
@@ -38,6 +39,24 @@ git branch
|
||||
|
||||
**🚨 警告:如果不创建测试分支,将违反ZenTao开发规范,必须立即停止操作并创建正确的分支!**
|
||||
|
||||
## 🔍 核心概念说明
|
||||
|
||||
### 测试用例 vs 测试步骤
|
||||
在ZenTao测试框架中,需要明确区分以下两个概念:
|
||||
|
||||
- **测试用例(Test Case)**:每个`.php`测试脚本文件对应一个测试用例,用于测试单个方法
|
||||
- **测试步骤(Test Step)**:在测试用例中,每个`r()...e()`语句对应一个测试步骤,用于验证特定场景
|
||||
|
||||
**示例说明:**
|
||||
```php
|
||||
// 这是一个测试用例:getUserById.php
|
||||
r($userTest->getByIdTest(1)) && p('account') && e('admin'); // 测试步骤1:正常用户查询
|
||||
r($userTest->getByIdTest(999)) && p() && e(false); // 测试步骤2:不存在用户查询
|
||||
r($userTest->getByIdTest(0)) && p() && e(false); // 测试步骤3:无效ID查询
|
||||
r($userTest->getByIdTest(-1)) && p() && e(false); // 测试步骤4:负数ID查询
|
||||
r($userTest->getByIdTest('abc')) && p() && e(false); // 测试步骤5:非数字ID查询
|
||||
```
|
||||
|
||||
## 测试框架架构
|
||||
|
||||
### 1. 目录结构规范
|
||||
@@ -75,9 +94,11 @@ module/{moduleName}/test/
|
||||
title=测试 {moduleName}Model::{methodName}();
|
||||
cid=0
|
||||
|
||||
- 测试用例1描述 @期望结果1
|
||||
- 测试用例2描述 @期望结果2
|
||||
- 测试用例3描述 @期望结果3
|
||||
- 测试步骤1描述 @期望结果1
|
||||
- 测试步骤2描述 @期望结果2
|
||||
- 测试步骤3描述 @期望结果3
|
||||
- 测试步骤4描述 @期望结果4
|
||||
- 测试步骤5描述 @期望结果5
|
||||
|
||||
*/
|
||||
```
|
||||
@@ -100,9 +121,12 @@ su('{username}');
|
||||
// 4. 创建测试实例
|
||||
${moduleName}Test = new {moduleName}Test();
|
||||
|
||||
// 5. 执行测试用例并断言
|
||||
r(${moduleName}Test->{methodName}Test({params})) && p('{property}') && e('{expected}'); // 用例1描述
|
||||
r(${moduleName}Test->{methodName}Test({params})) && p('{property}') && e('{expected}'); // 用例2描述
|
||||
// 5. 执行测试步骤并断言 (🔴 强制要求:至少5个测试步骤)
|
||||
r(${moduleName}Test->{methodName}Test({params})) && p('{property}') && e('{expected}'); // 测试步骤1描述
|
||||
r(${moduleName}Test->{methodName}Test({params})) && p('{property}') && e('{expected}'); // 测试步骤2描述
|
||||
r(${moduleName}Test->{methodName}Test({params})) && p('{property}') && e('{expected}'); // 测试步骤3描述
|
||||
r(${moduleName}Test->{methodName}Test({params})) && p('{property}') && e('{expected}'); // 测试步骤4描述
|
||||
r(${moduleName}Test->{methodName}Test({params})) && p('{property}') && e('{expected}'); // 测试步骤5描述
|
||||
```
|
||||
|
||||
**关键API说明:**
|
||||
@@ -350,11 +374,15 @@ fields:
|
||||
3. 理解业务逻辑和数据依赖关系
|
||||
4. 识别可能的异常情况
|
||||
|
||||
### 步骤3:设计测试用例
|
||||
1. 根据方法功能设计正常流程用例
|
||||
2. 设计边界值和异常输入用例
|
||||
### 步骤3:设计测试用例和测试步骤
|
||||
1. **设计测试用例**:每个测试脚本对应一个测试用例,用于测试单个方法
|
||||
2. **设计测试步骤**:在测试用例中设计多个测试步骤来验证不同场景
|
||||
- 正常流程测试步骤
|
||||
- 边界值测试步骤
|
||||
- 异常输入测试步骤
|
||||
3. 考虑数据库状态对测试的影响
|
||||
4. 确定断言点和期望结果
|
||||
4. 确定每个步骤的断言点和期望结果
|
||||
5. **🔴 强制要求:每个测试用例必须包含至少5个测试步骤**
|
||||
|
||||
### 步骤4:创建YAML数据文件(如需要)
|
||||
1. 分析方法依赖的数据表
|
||||
@@ -364,9 +392,10 @@ fields:
|
||||
|
||||
### 步骤5:编写测试脚本
|
||||
1. 创建测试执行脚本,包含完整的测试用例描述
|
||||
2. 实现单元测试类中的测试方法
|
||||
3. 配置数据准备和环境设置
|
||||
4. 编写全面的断言验证
|
||||
2. **🔴 强制要求:每个测试用例必须包含至少5个测试步骤(r()...e()语句)**
|
||||
3. 实现单元测试类中的测试方法
|
||||
4. 配置数据准备和环境设置
|
||||
5. 为每个测试步骤编写准确的断言验证
|
||||
|
||||
### 步骤6:验证测试脚本
|
||||
1. **必须使用** `test/runtime/ztf` 运行测试脚本(不能用php直接运行)
|
||||
@@ -547,11 +576,14 @@ r($userTest->createTest($invalidUser)) && p('errors,account') && e('用户名不
|
||||
- 避免测试间的数据污染
|
||||
- 考虑数据的业务合理性
|
||||
|
||||
### 3. 测试用例组织
|
||||
- 正常流程优先
|
||||
- 边界值测试完整
|
||||
- 异常处理覆盖全面
|
||||
- 用例描述清晰准确
|
||||
### 3. 测试用例和测试步骤组织
|
||||
- **测试用例层面**:每个测试脚本对应一个测试用例,专注于测试单个方法
|
||||
- **测试步骤层面**:在测试用例中合理组织测试步骤
|
||||
- 正常流程步骤优先
|
||||
- 边界值测试步骤完整
|
||||
- 异常处理步骤覆盖全面
|
||||
- 步骤描述清晰准确
|
||||
- **🔴 每个测试用例必须包含至少5个测试步骤**
|
||||
|
||||
### 4. 断言设计
|
||||
- 断言粒度适中
|
||||
@@ -592,16 +624,17 @@ r($userTest->createTest($invalidUser)) && p('errors,account') && e('用户名不
|
||||
### 🔴 强制检查项(必须100%完成)
|
||||
- [ ] **已创建测试分支**:分支名格式为 `unittest/{模块名}/{层次}/{方法名}/{大模型名}`
|
||||
- [ ] **当前在测试分支上工作**:通过 `git branch` 确认当前分支正确
|
||||
- [ ] **测试步骤数量符合要求**:每个测试用例包含至少5个测试步骤(r()...e()语句)
|
||||
- [ ] **测试脚本验证通过**:使用 `test/runtime/ztf` 运行测试,通过数为1,失败数为0
|
||||
- [ ] **已提交代码到本地**:使用正确格式的提交信息
|
||||
- [ ] **已推送到远程仓库**:执行 `git push` 推送测试分支
|
||||
- [ ] **已切换回开发分支**:完成后切换回原始开发分支
|
||||
|
||||
### 📝 代码质量检查项
|
||||
- [ ] **测试用例完整**:包含正常流程、边界值、异常情况测试
|
||||
- [ ] **断言准确**:所有断言都与实际输出匹配
|
||||
- [ ] **测试步骤完整**:测试用例包含正常流程、边界值、异常情况等测试步骤
|
||||
- [ ] **断言准确**:每个测试步骤的断言都与实际输出匹配
|
||||
- [ ] **数据准备充分**:zenData配置合理,覆盖测试所需场景
|
||||
- [ ] **注释清晰**:测试用例描述明确,期望结果准确
|
||||
- [ ] **注释清晰**:测试步骤描述明确,期望结果准确
|
||||
|
||||
### ⚠️ 常见错误避免
|
||||
- [ ] **避免直接在开发分支开发**:必须在测试分支上进行开发
|
||||
|
||||
Reference in New Issue
Block a user