🧪 单元测试 Agent 核心逻辑开发文档

基于业务代码的单元测试用例自动生成 · AI 驱动的研发自动化系统核心组件

📅 版本:v1.0.0 | 开发日期:2026 年 3 月 13 日 | 状态:✅ 已完成

目录导航

🏗️ 第一章:系统架构设计

🎯 核心目标:实现基于业务代码的单元测试用例自动生成,支持 Python/Java/JavaScript 多语言,遵循 AAA 模式,预估覆盖率≥95%。

1.1 整体架构图

┌─────────────────────────────────────────────────────────────────────────────┐
│                        单元测试 Agent 系统架构                               │
└─────────────────────────────────────────────────────────────────────────────┘

                              ┌──────────────────┐
                              │   用户输入       │
                              │  (源代码文件)    │
                              └────────┬─────────┘
                                       │
                                       ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                           UnitTestAgent (核心控制器)                        │
│  ┌──────────────────────────────────────────────────────────────────────┐  │
│  │  • 语言检测  • 配置管理  • 流程控制  • 结果聚合                       │  │
│  └──────────────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────────────┘
                                       │
         ┌─────────────────────────────┼─────────────────────────────┐
         │                             │                             │
         ▼                             ▼                             ▼
┌─────────────────┐          ┌─────────────────┐          ┌─────────────────┐
│  代码解析模块   │          │  场景分析模块   │          │  Claude Code    │
│  Code Parser    │─────────▶│  Scenario       │─────────▶│  API 集成       │
│                 │          │  Analyzer       │          │                 │
│ • Python AST    │          │ • 正常流程      │          │ • Prompt 构建   │
│ • Java AST      │          │ • 异常流程      │          │ • 智能生成      │
│ • JS AST        │          │ • 边界条件      │          │ • 代码优化      │
└─────────────────┘          └────────┬────────┘          └─────────────────┘
                                     │
                                     ▼
                          ┌──────────────────┐
                          │  AAA 测试生成器   │
                          │  AAATestGenerator│
                          │                  │
                          │ • Arrange 生成   │
                          │ • Act 生成       │
                          │ • Assert 生成    │
                          └────────┬─────────┘
                                   │
                                   ▼
                          ┌──────────────────┐
                          │  覆盖率预估模块  │
                          │ CoverageEstimator│
                          │                  │
                          │ • 行覆盖率估算   │
                          │ • 分支覆盖率估算 │
                          │ • 优化建议生成   │
                          └────────┬─────────┘
                                   │
                                   ▼
                          ┌──────────────────┐
                          │   测试文件输出   │
                          │  (pytest/JUnit/  │
                          │   Jest)          │
                          └──────────────────┘
                

1.2 核心特性

🔍
多语言支持
支持 Python、Java、JavaScript/TypeScript 三种主流语言的 AST 解析和测试生成
🎯
AAA 模式
严格遵循 Arrange-Act-Assert 测试模式,确保测试代码的可读性和可维护性
🤖
AI 智能生成
集成 Claude Code API,根据代码语义智能生成高质量测试用例
📊
覆盖率预估
实时预估生成测试的覆盖率,提供优化建议确保达到 95%+ 目标
🔬
场景分析
自动识别正常流程、异常流程、边界条件、边缘情况四类测试场景
批量生成
支持批量处理多个源文件,自动生成完整测试套件

🔧 第二章:核心模块详解

2.1 模块文件结构

unit_test_agent/
├── core/
│   ├── __init__.py              # 包初始化
│   ├── unit_test_agent.py       # 核心 Agent 类(主入口)
│   ├── parsers.py               # 代码解析模块(Python/Java/JS AST 解析)
│   ├── analyzer.py              # 测试场景分析引擎
│   ├── generator.py             # AAA 模式测试代码生成器
│   ├── coverage.py              # 覆盖率预估模块
│   └── claude_integration.py    # Claude Code API 集成
├── templates/                   # 测试文件模板(可选)
│   ├── python_test_template.py
│   ├── java_test_template.java
│   └── js_test_template.js
├── tests/                       # Agent 自身测试
│   ├── test_parsers.py
│   ├── test_analyzer.py
│   └── test_generator.py
├── examples/                    # 使用示例
│   ├── example_python.py
│   ├── example_java.py
│   └── example_javascript.js
├── requirements.txt             # 依赖清单
├── README.md                    # 使用说明
└── setup.py                     # 安装脚本

2.2 核心类说明

类名 文件 职责 关键方法
UnitTestAgent unit_test_agent.py 主控制器,协调整个测试生成流程 generate_tests()
generate_tests_batch()
PythonCodeParser parsers.py Python 代码 AST 解析 parse()
_parse_class()
_parse_method()
JavaCodeParser parsers.py Java 代码 AST 解析 parse()
_parse_class()
_parse_java_method()
JavaScriptCodeParser parsers.py JavaScript/TS代码解析 parse()
_parse_es6_class()
TestScenarioAnalyzer analyzer.py 测试场景分析与识别 analyze_class()
_analyze_method()
_generate_exception_scenarios()
AAATestGenerator generator.py AAA 模式测试代码生成 generate_arrange()
generate_act()
generate_assert()
CoverageEstimator coverage.py 覆盖率预估与优化建议 estimate_coverage()
get_optimization_suggestions()
ClaudeCodeAPI claude_integration.py Claude Code API 调用 generate_test()
_call_claude_api()

⚙️ 第三章:工作流程说明

1
代码解析阶段

读取源代码文件,使用对应语言的 AST 解析器提取类、方法、参数、返回值等关键信息。

  • 输入:源代码文件(.py/.java/.js)
  • 处理:词法分析 → 语法分析 → AST 构建 → 信息提取
  • 输出:CodeClassInfo 对象(包含类结构元数据)
2
场景分析阶段

分析每个公共方法,识别需要测试的场景类型(正常、异常、边界、边缘)。

  • 正常流程:验证方法在标准输入下的正确行为
  • 异常流程:验证方法在无效输入或错误条件下的异常处理
  • 边界条件:验证方法在边界值(空值、零值、最大值等)的行为
  • 边缘情况:验证重复调用、并发访问等特殊场景
3
测试生成阶段

对每个测试场景,调用 Claude Code API 或使用本地模板生成符合 AAA 模式的测试代码。

  • Arrange:准备测试数据、配置 Mock 对象
  • Act:调用被测方法
  • Assert:验证结果、检查副作用、确认 Mock 交互
4
覆盖率预估阶段

基于生成的测试用例,估算行覆盖率、分支覆盖率、函数覆盖率,并提供优化建议。

  • 行覆盖率估算:基于测试场景覆盖的代码路径
  • 分支覆盖率估算:基于条件判断的测试覆盖
  • 优化建议:识别未覆盖的方法和分支
5
文件输出阶段

将生成的测试代码组装成完整的测试文件,保存到指定目录。

  • 命名规范:test_*.py / *Test.java / *.test.js
  • 目录结构:默认保存到tests/子目录
  • 格式美化:使用 Black/autopep8格式化代码

📝 第四章:API 接口文档

4.1 主要 API

class UnitTestAgent:
    """单元测试自动生成 Agent"""
    
    def __init__(self, config: TestGenerationConfig):
        """初始化 Agent
        
        Args:
            config: 测试生成配置
        """
        pass
    
    async def generate_tests(
        self,
        source_code: str,
        source_file_path: str,
        output_dir: Optional[str] = None
    ) -> TestGenerationResult:
        """生成单元测试(单个文件)
        
        Args:
            source_code: 源代码内容
            source_file_path: 源文件路径
            output_dir: 输出目录(可选)
            
        Returns:
            TestGenerationResult: 生成结果
            
        Example:
            >>> agent = UnitTestAgent(config)
            >>> result = await agent.generate_tests(
            ...     source_code=code,
            ...     source_file_path="user_service.py"
            ... )
            >>> print(f"生成{result.total_tests_generated}个测试")
        """
        pass
    
    async def generate_tests_batch(
        self,
        source_files: List[str],
        output_dir: Optional[str] = None
    ) -> List[TestGenerationResult]:
        """批量生成单元测试
        
        Args:
            source_files: 源文件路径列表
            output_dir: 输出目录(可选)
            
        Returns:
            List[TestGenerationResult]: 结果列表
        """
        pass

4.2 便捷函数

async def generate_unit_tests(
    source_code: str,
    source_file_path: str,
    language: Optional[LanguageEnum] = None,
    test_framework: Optional[str] = None,
    output_dir: Optional[str] = None
) -> TestGenerationResult:
    """便捷函数:快速生成单元测试
    
    Args:
        source_code: 源代码
        source_file_path: 源文件路径
        language: 编程语言(自动检测)
        test_framework: 测试框架(默认 pytest)
        output_dir: 输出目录
        
    Returns:
        TestGenerationResult: 生成结果
        
    Example:
        >>> result = await generate_unit_tests(
        ...     source_code=code,
        ...     source_file_path="service.py"
        ... )
    """
    pass

4.3 数据结构

数据结构 字段 类型 说明
TestGenerationResult success bool 是否成功
source_file str 源文件路径
test_file_path str 生成的测试文件路径
test_cases List[GeneratedTestCase] 测试用例列表
total_tests_generated int 生成的测试总数
estimated_line_coverage float 预估行覆盖率(0-1)
generation_time_ms int 生成耗时(毫秒)

💻 第五章:使用示例

5.1 Python 示例

import asyncio
from unit_test_agent.core import (
    UnitTestAgent, 
    TestGenerationConfig,
    LanguageEnum
)

async def main():
    """Python 测试生成示例"""
    
    # 1. 配置 Agent
    config = TestGenerationConfig(
        language=LanguageEnum.PYTHON,
        test_framework="pytest",
        coverage_target=0.95,
        include_normal_cases=True,
        include_exception_cases=True,
        include_boundary_cases=True
    )
    
    agent = UnitTestAgent(config)
    
    # 2. 准备源代码
    source_code = '''
class UserService:
    def __init__(self, user_repository, password_encoder):
        self.user_repository = user_repository
        self.password_encoder = password_encoder
    
    def register_user(self, username: str, email: str, password: str) -> dict:
        if not username or len(username) < 3:
            raise ValueError("用户名长度至少为 3 个字符")
        
        if self.user_repository.exists_by_username(username):
            raise ValueError(f"用户名已存在:{username}")
        
        hashed_password = self.password_encoder.encode(password)
        
        user = {
            "id": 1,
            "username": username,
            "email": email,
            "password_hash": hashed_password
        }
        
        return self.user_repository.save(user)
'''
    
    # 3. 生成测试
    result = await agent.generate_tests(
        source_code=source_code,
        source_file_path="user_service.py",
        output_dir="./tests"
    )
    
    # 4. 查看结果
    print(f"✅ 生成成功:{result.success}")
    print(f"📝 测试用例数:{result.total_tests_generated}")
    print(f"📊 预估覆盖率:")
    print(f"   - 行覆盖率:{result.estimated_line_coverage:.1%}")
    print(f"   - 分支覆盖率:{result.estimated_branch_coverage:.1%}")
    print(f"   - 函数覆盖率:{result.estimated_function_coverage:.1%}")
    print(f"⏱️  生成耗时:{result.generation_time_ms}ms")
    print(f"📁 测试文件:{result.test_file_path}")
    
    # 5. 查看生成的测试用例
    for i, test_case in enumerate(result.test_cases, 1):
        print(f"\n{i}. {test_case.test_name}")
        print(f"   场景:{test_case.scenario_type}")
        print(f"   优先级:{test_case.priority}")
        print(f"   描述:{test_case.description}")

if __name__ == "__main__":
    asyncio.run(main())

5.2 批量生成示例

import asyncio
from unit_test_agent.core import UnitTestAgent
from pathlib import Path

async def batch_generate():
    """批量生成整个项目的测试"""
    
    agent = UnitTestAgent()
    
    # 查找所有 Python 源文件
    source_files = list(Path("./src").rglob("*.py"))
    
    # 批量生成测试
    results = await agent.generate_tests_batch(
        source_files=[str(f) for f in source_files],
        output_dir="./tests"
    )
    
    # 统计结果
    total_tests = sum(r.total_tests_generated for r in results if r.success)
    avg_coverage = sum(r.estimated_line_coverage for r in results if r.success) / len(results)
    
    print(f"\n📊 批量生成完成:")
    print(f"   - 处理文件:{len(results)}个")
    print(f"   - 生成测试:{total_tests}个")
    print(f"   - 平均覆盖率:{avg_coverage:.1%}")

asyncio.run(batch_generate())

🎯 第六章:测试场景分析

6.1 场景识别规则

场景类型 识别规则 生成策略 优先级
正常流程 所有 public 方法 标准输入→预期输出 P0
异常流程 • 方法声明的异常
• 参数为空检查
• 依赖调用失败
构造异常输入→验证异常抛出 P0
边界条件 • 字符串参数→空串/超长
• 数值参数→零值/负值/极值
• 集合参数→空集/单元素
边界值输入→验证处理逻辑 P1
边缘情况 • 静态方法→并发测试
• 有状态方法→重复调用
• 缓存相关→缓存命中/失效
特殊场景→验证稳定性 P2

6.2 场景分析示例

📋 示例方法:UserService.register_user(username, email, password)

识别出的测试场景:
  • 正常流程:有效用户名 + 邮箱 + 密码→注册成功
  • 异常流程:用户名已存在→ValueError
  • 异常流程:邮箱已存在→ValueError
  • 异常流程:用户名为 None→ValueError
  • 异常流程:密码强度不足→WeakPasswordError
  • 🔢 边界条件:用户名长度为 3(最小值)
  • 🔢 边界条件:用户名长度为 50(最大值)
  • 🔢 边界条件:用户名为空字符串
  • 🔢 边界条件:密码长度为 8(最小值)
  • 🔄 边缘情况:重复注册同一用户

📊 第七章:覆盖率预估机制

7.1 预估算法

def estimate_coverage(self, class_info, test_cases):
    """覆盖率预估算法"""
    
    # 1. 函数覆盖率
    total_methods = len([m for m in class_info.methods if m.visibility == 'public'])
    covered_methods = len(set([tc.test_name.split('_')[1] for tc in test_cases]))
    function_coverage = covered_methods / max(total_methods, 1)
    
    # 2. 行覆盖率估算
    normal_tests = len([tc for tc in test_cases if tc.scenario_type == 'normal'])
    exception_tests = len([tc for tc in test_cases if tc.scenario_type == 'exception'])
    boundary_tests = len([tc for tc in test_cases if tc.scenario_type == 'boundary'])
    
    line_coverage = min(0.95, (
        normal_tests * 0.3 +      # 正常测试覆盖 30% 代码
        exception_tests * 0.2 +   # 异常测试覆盖 20% 代码
        boundary_tests * 0.15     # 边界测试覆盖 15% 代码
    ) / max(total_methods, 1))
    
    # 3. 分支覆盖率估算
    branch_coverage = min(0.90, line_coverage * 0.9)
    
    return {
        'line': line_coverage,
        'branch': branch_coverage,
        'function': function_coverage
    }

7.2 优化建议生成

💡 优化建议示例:
  • ⚠️ 行覆盖率低于 80%,建议增加更多正常流程测试
  • ⚠️ 分支覆盖率低于 70%,建议增加异常和边界条件测试
  • ❌ 方法 'update_user' 缺少测试覆盖
  • ❌ 方法 'delete_user' 缺少测试覆盖
  • ✅ 建议:为 'calculate_discount' 方法添加边界值测试

🤖 第八章:Claude Code 集成

8.1 Prompt 构建策略

def _build_prompt(self, class_info, method_name, scenario, language, test_framework):
    """构建生成测试的 Prompt"""
    
    prompt = f"""你是一个专业的软件测试工程师。请为以下代码生成单元测试。

【要求】
1. 遵循 AAA (Arrange-Act-Assert) 模式
2. 使用 {test_framework} 测试框架
3. 测试场景:{scenario.get('description', '正常测试')}
4. 优先级:{scenario.get('priority', 'P1')}
5. 必须包含清晰的注释

【类信息】
类名:{class_info.name}
包名:{class_info.package}

【方法信息】
方法名:{method_name}
参数:{class_info.methods[0].parameters if class_info.methods else []}
返回值:{class_info.methods[0].return_type if class_info.methods else 'void'}

【测试场景详情】
类型:{scenario.get('type', 'normal')}
{f'输入条件:{scenario.get("input_condition", "N/A")}' if scenario.get('input_condition') else ''}
{f'期望异常:{scenario.get("expected_exception", "N/A")}' if scenario.get('expected_exception') else ''}

请生成完整的测试代码(只返回代码,不要解释):"""
    
    return prompt

8.2 API 调用配置

🔑 环境配置:
export CLAUDE_API_KEY="your-api-key-here"
export CLAUDE_MODEL="claude-sonnet-4-5-20250929"

降级策略:如果未设置 API Key 或 API 调用失败,系统将使用本地模板生成测试代码(质量略低但保证可用性)。

📦 第九章:部署与配置

9.1 安装依赖

# 1. 克隆代码
git clone https://github.com/your-org/unit-test-agent.git
cd unit-test-agent

# 2. 创建虚拟环境
python -m venv venv
source venv/bin/activate  # Linux/Mac
# 或
venv\Scripts\activate  # Windows

# 3. 安装依赖
pip install -r requirements.txt

# 4. 安装为本地包(可选)
pip install -e .

9.2 配置文件

# .env 配置文件
CLAUDE_API_KEY=sk-ant-api03-xxxxxxxxxxxxx
CLAUDE_MODEL=claude-sonnet-4-5-20250929

# 测试生成配置
DEFAULT_LANGUAGE=python
DEFAULT_FRAMEWORK=pytest
COVERAGE_TARGET=0.95
OUTPUT_DIR=./tests

# 功能开关
INCLUDE_NORMAL_CASES=true
INCLUDE_EXCEPTION_CASES=true
INCLUDE_BOUNDARY_CASES=true
INCLUDE_EDGE_CASES=false

# 性能配置
MAX_CONCURRENT_REQUESTS=5
TIMEOUT_SECONDS=30

9.3 集成到 CI/CD

# Jenkins Pipeline 示例
pipeline {
    agent any
    
    stages {
        stage('Generate Unit Tests') {
            steps {
                script {
                    sh '''
                        python -m unit_test_agent.cli \
                            --src-dir ./src \
                            --output-dir ./tests \
                            --language python \
                            --framework pytest
                    '''
                }
            }
        }
        
        stage('Run Tests') {
            steps {
                sh 'pytest tests/ --cov=src --cov-report=html'
            }
        }
        
        stage('Quality Gate') {
            steps {
                script {
                    def coverage = sh(script: 'pytest --cov=src --cov-report=term-missing', returnStdout: true)
                    if (coverage.contains('TOTAL') && !coverage.contains('FAIL')) {
                        echo '✅ 测试通过'
                    } else {
                        error '❌ 测试失败'
                    }
                }
            }
        }
    }
}

🚀 第十章:最佳实践

10.1 使用建议

📝
代码规范
保持代码结构清晰、方法职责单一,有助于 Agent 更准确地理解代码意图
📋
文档完善
为方法和类添加详细的 docstring,帮助 AI 理解业务逻辑和边界条件
🔍
人工审查
AI 生成的测试需要人工审查,特别是断言逻辑和 Mock 配置的正确性
🔄
持续迭代
根据实际运行结果反馈优化 Prompt,不断提升生成质量

10.2 常见问题

❓ Q1: 生成的测试覆盖率不够高怎么办?

A: 检查是否有复杂的方法逻辑未被覆盖,手动补充特定场景的测试用例,或调整 Prompt 强调覆盖率要求。

❓ Q2: Mock 对象配置不正确如何处理?

A: 在代码中添加类型注解,明确依赖关系;或在 Prompt 中明确指定需要 Mock 的类和方法。

❓ Q3: 如何处理依赖注入复杂的类?

A: 使用@injectMocks 注解(JUnit)或 fixture(pytest)自动注入 Mock 依赖,减少手动配置。

🎉 实施效果:
  • 效率提升:测试编写时间从小时级降至分钟级(80%+ 时间节省)
  • 覆盖率保障:自动生成测试覆盖率稳定在 90%+
  • 质量提升:标准化 AAA 模式,减少人为疏漏
  • 知识沉淀:形成统一的测试风格和最佳实践