From 379f133cb1e9d2ecd2fa9e065559e823dc8dbf7e Mon Sep 17 00:00:00 2001 From: liugang Date: Sat, 23 Aug 2025 08:00:23 +0800 Subject: [PATCH] * [misc] Refine unit test guide with clarified concepts and 5-step requirement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- zentao-unit-test-guide.md | 75 ++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/zentao-unit-test-guide.md b/zentao-unit-test-guide.md index 10100d7c9d..d4d90d445c 100644 --- a/zentao-unit-test-guide.md +++ b/zentao-unit-test-guide.md @@ -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配置合理,覆盖测试所需场景 -- [ ] **注释清晰**:测试用例描述明确,期望结果准确 +- [ ] **注释清晰**:测试步骤描述明确,期望结果准确 ### ⚠️ 常见错误避免 - [ ] **避免直接在开发分支开发**:必须在测试分支上进行开发