# 测试用例生成 -- 智能测试用例生成 ## 输入要求 1. **被测代码**(必填):需要测试的函数/类/模块 2. **测试框架**(必填):如Jest、Pytest、JUnit、Go testing 3. **编程语言**(必填):代码使用的语言 4. **测试类型**(可选):单元测试/集成测试/全部,默认全部 5. **已有测试**(可选):如果已有部分测试需要补充 6. **专项要求**(可选):安全测试/性能测试/长任务测试/兼容性测试 ## 执行流程 ### 第一步:Spec场景覆盖检查 生成测试前先检查spec中的scenario: - **如有spec**:确保每个scenario至少有一个对应的测试用例 - **spec → 测试映射**: ``` Scenario: [scenario名称] → Test: [测试用例名称] ``` - **无spec**:基于代码逻辑生成测试,但提示建议补充spec ### 第二步:代码分析 - 识别被测函数的输入参数和返回值 - 识别条件分支(if/else、switch、try-catch) - 识别外部依赖(数据库、API、文件系统) - 识别边界条件(空值、空数组、最大值、最小值) - 识别安全触发面:外部输入、权限、SQL、HTML输出、CSRF、上传、反序列化、敏感信息 - 识别性能触发面:循环、批量处理、分页、数据库查询、网络调用、缓存、长任务 - 识别长任务触发面:Init 创建、Step 分批、Poll 查询、重试、取消、超时、断点续跑 ### 第三步:生成测试场景 | 场景类型 | 说明 | 示例 | | - | - | - | | **正常路径** | 标准输入,预期成功 | 正常参数调用 | | **边界条件** | 临界值输入 | 空数组、最大长度、0值 | | **异常路径** | 错误输入,预期失败 | null、负数、类型错误 | | **状态相关** | 依赖对象状态的测试 | 对象初始化后/操作后 | | **并发相关** | 多线程/协程场景 | 同时读写、竞态条件 | | **安全相关** | 验证注入、越权、输出转义和令牌校验 | SQL注入payload、XSS输入、缺失CSRF token、越权访问 | | **性能相关** | 验证响应时间、查询次数、批量规模和资源占用 | 1000条批处理、分页查询、慢查询阈值 | | **长任务相关** | 验证 Init-Step-Poll 全链路和失败恢复 | Init返回task_id、Step分批推进、Poll状态变化、取消/重试 | ### 第四步:编写测试代码 - 使用 Arrange-Act-Assert 结构 - 为外部依赖创建Mock/Stub - 使用描述性的测试名称 - 每个测试只验证一个概念 - 安全测试必须包含恶意输入和权限负例,断言拒绝、转义或错误码 - 性能测试必须写明数据规模、阈值和统计口径,不能只写"性能正常" - 长任务测试必须覆盖 Init、Step、Poll、失败重试、取消、超时和幂等 ### 第五步:覆盖率分析 - 语句覆盖率预估 — 按已测试语句数 / 被测函数总语句数估算;生成测试后统计 Arrange-Act-Assert 覆盖的代码行数占比 - 分支覆盖率预估 — 按已覆盖分支数 / 被测函数总分支数估算(每个 if/else/switch/try-catch 的每个分支计1);生成测试后统计触发过的条件分支占比 - 未覆盖路径说明 - **安全覆盖检查**:确认输入校验、权限、输出转义、CSRF、文件上传、反序列化等触发面是否有正反例 - **性能覆盖检查**:确认核心路径有数据规模、耗时阈值、查询次数或资源占用断言 - **长任务覆盖检查**:确认 Init-Step-Poll、重试、取消、超时、断点续跑至少覆盖核心路径 - **Spec覆盖检查**:确认所有scenario都有对应测试 ### 第六步:记录到项目记忆 测试用例生成完成后,将关键决策记录到项目记忆(参见 `project-memory-management.md`): - 记录测试策略选择 - 记录 Mock/Stub 约定和命名规范 - 更新测试覆盖率基线,作为后续测试的质量参考 ## 实战请求示例 ### 示例一:接口功能测试 ```text 帮我给登录接口生成测试用例。 框架:Laravel Feature Test / PHPUnit。 接口:POST /api/login。 输入:email、password。 覆盖:成功登录、密码错误、邮箱格式错误、账号禁用、频率限制。 安全:断言不会返回 password_hash、token 只在成功时返回。 验证:给出测试文件路径、运行命令和预期通过数。 ``` 优先加载:`test-generation.md`、`api-design.md`、`laravel-testing.md`。 ### 示例二:长任务测试 ```text 帮我给批量刷新缓存任务生成测试。 架构:Init-Step-Poll。 覆盖:Init 返回 task_id;Step 每批 50 条;Poll 返回 percent;失败可重试;取消后不能继续执行。 边界:空数据、超大数据、重复 Step、无权限访问。 验证:给出单元测试和手动接口测试步骤。 ``` 优先加载:`test-generation.md`、`api-design.md`、`cms-development.md`。 ## 输出格式 ``` ## 测试用例报告 **被测函数**:[函数名] **测试框架**:[框架] **生成测试数**:[X]个 ## 测试场景分析 | 场景 | 输入 | 预期输出 | 类型 | |------|------|---------|------| | [场景1] | [输入] | [输出] | 正常路径 | | [场景2] | [输入] | [输出] | 边界条件 | | [场景3] | [输入] | [输出] | 异常路径 | | [场景4] | [输入] | [输出] | 安全/性能/长任务 | ## 测试代码 ```[语言] [完整测试代码] ``` ## 覆盖率预估 - **语句覆盖**:[X]% - **分支覆盖**:[X]% - **安全覆盖**:[已覆盖/未覆盖,说明] - **性能覆盖**:[已覆盖/未覆盖,说明] - **长任务覆盖**:[已覆盖/不涉及,说明] - **未覆盖路径**:[说明] ## 运行命令 ```bash [运行测试的命令] ``` ``` ## 质量标准 - 每个测试必须有明确的Arrange-Act-Assert结构 - 测试名称必须描述行为和预期结果(如`shouldReturnErrorWhenInputIsNull`) - 边界条件必须覆盖:空值、空集合、最大值、最小值、边界值+1/-1 - 异常测试必须验证具体的异常类型和错误消息 - 安全测试必须覆盖适用风险:SQL注入、XSS、CSRF、权限绕过、文件上传、反序列化、敏感信息泄露 - 性能测试必须定义数据规模、响应时间/查询次数/内存阈值,并说明环境前提 - 长任务测试必须覆盖 Init 创建、Step 分批、Poll 查询、失败重试、取消、超时和幂等 - 外部依赖(数据库、API、文件)必须使用Mock,不能真实调用 - 不得生成无意义的测试(如测试getter/setter且不做断言) ### 算法边界用例清单(图与递归算法) 仅覆盖「空值/空集合/最大值/边界值±1」等**值域边界**不足以拦住图与递归算法缺陷。环检测这类算法三次迭代都没写对,根因是测试侧缺一张能拦住它的**结构边界**用例表。 **边界应从不变量推导,而不是背诵**:凡是会让某个不变量被违反的结构,就是必须测的边界。先按 `karpathy-coding-guidelines.md` 不变量推导三步法推出「不变量命题 + 终止度量 + 守恒关系」,再取其逆否命题枚举边界——这样边界表从"背下来的表"变成"推导出来的表",面对没写进表的全新算法也能自己推出该测什么。 任何图遍历 / 递归 / 状态机 / 依赖解析算法,除值域边界外必须补齐以下结构化边界(以有向图环检测为例,可推广到树、DAG、拓扑排序、可达性分析等): | 边界 | 结构 | 断言要点 | | - | - | - | | 0 节点 | 空图 | cycle=0,且不抛异常 | | 1 节点 | 单点无环 | cycle=0 | | 自环 | 单点指向自身 | cycle=1(或按业务语义) | | 两节点互环(down) | A→B→A | cycle=1,且遍历方向与边有向性一致 | | 两节点互环(both) | A⇄B(双向/无向) | cycle=1 | | 三环 | A→B→C→A | cycle=1,且不重复计数 | | 菱形 DAG | A→B→D, A→C→D | cycle=0(断言无环) | | 平行边 | A→B 出现两次 | 覆盖不重复、环计数不翻倍 | | up 方向 | 反向遍历同图 | 边方向与遍历方向一致,结果不为负 | - **递归不变量断言**:对每个递归 / DFS,必须断言不变量(invariant)在每次递归入口与出口成立,例如「已访问集合不含回边指向的节点」「递归栈深不超过节点总数」「计数单调不减」。流程跑通 ≠ 结果正确,必须有可判定的结构化断言。 - **回边判定黑盒断言**:不要只测"能跑完",要断言具体结果(环数、环成员、是否标记、是否重复)。「流程跑通但结果错」是这类缺陷的典型漏网形态。 - **property-based testing 提示**:对纯函数式算法(排序、环检测、拓扑排序、去重),用 property-based 框架(Python Hypothesis、JS fast-check、Java jqwik 等)生成随机结构,断言稳定性质,避免测试依赖输入顺序或样本偶然性: - 单调性:给图加入一条边后,环数单调不减; - 交换律:重排节点顺序 / 反转子图,结果不变; - 对任意合法 DAG,拓扑排序结果与任一合法顺序一致。 ## 失败回退机制 | 步骤 | 失败条件 | 回退目标 | 最大重试 | 不可恢复时升级路径 | | - | - | - | - | - | | 第一步:Spec场景覆盖检查 | 无spec或spec场景与代码实现不一致 | 基于代码逻辑生成测试,标注"无spec对照" | 1 | 建议先走 Spec驱动开发 补全spec | | 第二步:代码分析 | 代码量过大,分支/依赖识别超限 | 按函数分批分析,每批输出局部测试 | 0 | 建议缩小测试范围或分模块生成 | | 第三步:生成测试场景 | 边界条件难以枚举 | 优先覆盖核心路径 + 已知边界,标注"边界待补" | 2 | 输出场景骨架,建议人工补充边界 | | 第四步:编写测试代码 | Mock/Stub设置复杂,外部依赖难以隔离 | 降级为集成测试,标注"未完全Mock" | 2 | 输出测试框架骨架,建议人工补全Mock | | 第五步:覆盖率分析 | 覆盖率无法量化(无运行环境) | 输出预估覆盖率,标注"未实际运行" | 1 | 建议用户本地运行测试后回填实际覆盖率 | | 第六步:记录到项目记忆 | 项目记忆系统不可用 | 输出测试策略到本地文件 | 1 | 标注"策略未沉淀",提示用户手动保存 | ## 关联 reference - **frontend-design**(前端设计)— 前端页面或组件测试需参考 `frontend-design` 的交互状态、响应式断点和可访问性要求 - **api-design**(API设计)— API 和长任务测试需参考 `api-design` 的认证、错误码、分页和 Init-Step-Poll 契约 - **cms-development**(CMS二次开发)— CMS/PHP 测试需参考 `cms-development` 的权限、CSRF、输出转义和批处理规则 - **mysql-database**(MySQL数据库)— SQL 和性能测试需参考 `mysql-database` 的参数绑定、索引、事务和 EXPLAIN 标准 - **code-review**(代码审查)— 生成前可用 `code-review` 确保被测代码逻辑正确 - **bug-diagnosis**(Bug诊断)— 修复Bug后可用 `test-generation` 生成回归测试 - **code-generation**(代码生成)— 生成代码后可用 `test-generation` 生成配套测试 - **project-memory-management**(项目记忆管理)— 记录测试策略、Mock/Stub 约定和测试覆盖率基线