# Test Generator

> 【测试生成】从源代码自动生成 pytest 测试用例。分析代码逻辑、分支路径、边界条件，生成覆盖正常路径、异常场景、边界条件的测试代码。 触发时机： - 用户要求"生成测试"、"写测试"、"加单元测试" - 编码完成后需要补充测试覆盖 - wo-yao-yan-pai 审查完成后需要补充测试 不依赖外部测试框架，纯 prompt 模板驱动。

- Skill: `afine907/test-generator` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add afine907/test-generator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/afine907/test-generator/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: afine907 (https://skillmd.com/u/afine907)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/afine907/test-generator

---


# Test Generator — 测试代码生成 Agent

从源代码自动生成 pytest 测试用例。


## Goal

从源代码自动生成 pytest 测试用例。分析代码逻辑、分支路径、边界条件，生成覆盖正常路径、异常场景、边界条件的测试代码

## Trigger

- 用户要求"生成测试"、"写测试"、"加单元测试"
  - 编码完成后需要补充测试覆盖
  - wo-yao-yan-pai 审查完成后需要补充测试

## 工作流程

```
源代码 → 分析结构 → 识别测试场景 → 生成测试代码 → 输出测试文件
```

## Step 1: 分析源代码结构

分析目标代码的以下维度：

### 函数/方法分析
- 函数签名（参数、返回值、异常声明）
- 控制流（if/else、循环、match/case）
- 分支条件数量（圈复杂度）
- 外部依赖（DB、网络、文件系统、第三方 API）

### 类分析（面向对象代码）
- 构造函数参数及默认值
- 公有/私有方法划分
- 类级别状态（实例变量）
- 继承关系（需要 mock 父类吗？）

### 识别测试场景

| 场景类型 | 覆盖内容 | 必须？ |
|----------|----------|--------|
| ✅ 正常路径 | 典型输入，期望正常返回 | 必须 |
| ✅ 边界条件 | 空值、极值、类型边界、长度极限 | 必须 |
| ✅ 异常路径 | 非法输入、权限不足、资源不存在 | 必须 |
| ✅ 错误处理 | 外部依赖异常、超时、重试逻辑 | 建议 |
| ⭐ 参数化 | 多组输入输出覆盖 | 建议 |

## Step 2: 确定 mock 策略

识别外部依赖并确定 mock 边界：

```python
# 1. 数据库操作 → mock repository/DAO 层
# 2. HTTP 请求 → mock 响应（requests / httpx）
# 3. 文件系统 → tmp_path fixture（pytest 内置）
# 4. 环境变量 → monkeypatch（pytest 内置）
# 5. 时间依赖 → freezegun / time_mock
# 6. 随机数 → 固定 seed 或 mock random
```

**规则**：
- Mock 外部 IO，不 mock 业务逻辑
- 集成测试不 mock，用真实依赖
- 纯函数不需要 mock，直接测试

## Step 3: 生成测试代码

按以下模板输出 pytest 测试文件：

```python
"""
Test suite for {module_name}
"""
import pytest
from unittest.mock import Mock, patch, MagicMock
from {module_path} import {function_names}


class Test{class_name}:
    """Tests for {class_name}"""

    # ── 正常路径 ──────────────────────────────────

    def test_{scenario_normal(self}):
        """{description of normal scenario}"""
        # Arrange
        input_data = {typical input}
        expected = {expected output}

        # Act
        result = {function}(input_data)

        # Assert
        assert result == expected

    # ── 边界条件 ──────────────────────────────────

    @pytest.mark.parametrize("input,expected", [
        ({case1_input}, {case1_expected}),
        ({case2_input}, {case2_expected}),
    ])
    def test_{scenario_boundary}(self, input, expected):
        result = {function}(input)
        assert result == expected

    # ── 异常路径 ──────────────────────────────────

    def test_{scenario_error(self}):
        """{description of error scenario}"""
        with pytest.raises({ExceptionType}):
            {function}({invalid_input})

    # ── Mock 外部依赖 ─────────────────────────────

    @patch("{module}.{dependency}")
    def test_{scenario_with_mock(self}, mock_dep):
        mock_dep.return_value = {mock_data}
        result = {function}({input})
        assert result == {expected}
```

## Step 4: 输出规范

每个源代码文件对应生成一个 `test_{filename}.py` 文件：

```
src/
  utils/
    helper.py             → tests/test_helper.py
    validator.py          → tests/test_validator.py
  services/
    auth.py               → tests/services/test_auth.py
```

**测试文件结构**：
```python
"""
Auto-generated tests for {source_file}
Generated by test-generator
"""
```

## 质量检查

输出前确认：
- [ ] 每个公有函数/方法至少有一个测试
- [ ] 覆盖了正常路径
- [ ] 覆盖了主要边界条件
- [ ] 覆盖了关键异常路径
- [ ] Mock 了所有外部 IO
- [ ] 测试命名清晰（`test_{function}_{scenario}`）
- [ ] 使用了 Arrange-Act-Assert 模式
- [ ] 参数化测试覆盖多组数据

## 快速使用

```
# 生成单个文件的测试
生成测试 src/services/auth.py

# 为整个模块生成测试
为 utils 模块生成测试

# 为 wo-yao-yan-pai 审查结果补充测试
刚才审查的代码，生成对应的测试
```

## 参考资料

- 测试模板: [references/templates.md](references/templates.md)

