Files
autogen/agents/qa_agent.py

222 lines
6.1 KiB
Python
Raw Normal View History

2026-03-12 13:27:03 +08:00
"""
QA Agent - 测试工程师智能体
负责测试用例创建和 TDD 实践
"""
from autogen import AssistantAgent
from typing import Dict, Any, Optional
import os
from pathlib import Path
from config.llm_config import get_agent_llm_config, QA_PROMPT
class QAAgent:
"""测试工程师 Agent负责生成测试用例和测试脚本"""
def __init__(self, llm_config: Optional[Dict] = None):
"""
初始化 QA Agent
Args:
llm_config: LLM 配置
"""
self.llm_config = llm_config or get_agent_llm_config("QA_Agent")
self.agent = AssistantAgent(
name="QA_Agent",
system_message=QA_PROMPT,
llm_config=self.llm_config,
description="资深测试工程师,专注于自动化测试和 TDD 实践",
human_input_mode="NEVER"
)
self.workspace_dir = Path("workspace")
self.workspace_dir.mkdir(exist_ok=True)
def generate_test_cases(self, srs_content: str) -> str:
"""
根据 SRS 生成测试用例
Args:
srs_content: SRS 文档内容
Returns:
生成的测试用例内容
"""
prompt = f"""
请根据以下 SRS 文档生成完整的测试用例
{self._truncate(srs_content, 3000)}
请生成
1. Pytest 测试脚本包含完整的测试函数
2. BDD 风格的测试场景描述
3. 测试数据准备
4. 预期结果验证
确保遵循 TDD 原则测试先于代码存在
"""
response = self.agent.generate_reply(
messages=[{"role": "user", "content": prompt}]
)
test_content = response if isinstance(response, str) else str(response)
# 保存测试文件
test_file = self.workspace_dir / "test_battery_health.py"
with open(test_file, 'w', encoding='utf-8') as f:
f.write(test_content)
print(f"✅ 测试用例已生成:{test_file}")
return test_content
def create_bdd_scenarios(self, srs_content: str) -> str:
"""
创建 BDD 风格的测试场景
Args:
srs_content: SRS 文档内容
Returns:
BDD 测试场景描述
"""
prompt = f"""
请根据 SRS 创建 BDD (Behavior-Driven Development) 测试场景
{self._truncate(srs_content, 2000)}
请使用 Given-When-Then 格式描述每个测试场景
- Feature: 功能描述
- Scenario: 场景描述
- Given: 前置条件
- When: 操作
- Then: 预期结果
输出为 Markdown 格式
"""
response = self.agent.generate_reply(
messages=[{"role": "user", "content": prompt}]
)
bdd_content = response if isinstance(response, str) else str(response)
# 保存 BDD 场景文件
bdd_file = self.workspace_dir / "bdd_scenarios.md"
with open(bdd_file, 'w', encoding='utf-8') as f:
f.write(bdd_content)
print(f"✅ BDD 场景已生成:{bdd_file}")
return bdd_content
def analyze_test_coverage(self, test_code: str, srs_content: str) -> Dict[str, Any]:
"""
分析测试覆盖率
Args:
test_code: 测试代码
srs_content: SRS 文档
Returns:
覆盖率分析报告
"""
prompt = f"""
请分析以下测试代码对 SRS 需求的覆盖情况
SRS 需求
{self._truncate(srs_content, 1500)}
测试代码
{self._truncate(test_code, 2000)}
请输出
1. 已覆盖的需求列表
2. 未覆盖的需求列表
3. 覆盖率百分比
4. 改进建议
"""
response = self.agent.generate_reply(
messages=[{"role": "user", "content": prompt}]
)
coverage_report = response if isinstance(response, str) else str(response)
# 保存报告
report_file = self.workspace_dir / "coverage_report.md"
with open(report_file, 'w', encoding='utf-8') as f:
f.write(coverage_report)
return {"report": coverage_report, "file": str(report_file)}
def _truncate(self, text: str, max_length: int) -> str:
"""截断文本以避免超出上下文限制"""
if len(text) <= max_length:
return text
return text[:max_length] + "... [内容已截断]"
def run_tests(self, test_file_pattern: str = "test_*.py") -> Dict[str, Any]:
"""
执行测试需要实际运行 pytest
Args:
test_file_pattern: 测试文件模式
Returns:
测试结果字典
"""
import subprocess
import sys
try:
# 使用 pytest 执行测试
result = subprocess.run(
[sys.executable, "-m", "pytest",
str(self.workspace_dir / test_file_pattern),
"-v", "--tb=short"],
capture_output=True,
text=True,
timeout=60
)
return {
"success": result.returncode == 0,
"stdout": result.stdout,
"stderr": result.stderr,
"returncode": result.returncode
}
except subprocess.TimeoutExpired:
return {
"success": False,
"error": "测试执行超时"
}
except Exception as e:
return {
"success": False,
"error": str(e)
}
def create_qa_agent(llm_config: Optional[Dict] = None) -> AssistantAgent:
"""
创建 QA AgentAutoGen 原生格式
Args:
llm_config: LLM 配置
Returns:
AutoGen AssistantAgent 实例
"""
config = llm_config or get_agent_llm_config("QA_Agent")
agent = AssistantAgent(
name="QA_Agent",
system_message=QA_PROMPT,
llm_config=config,
description="资深测试工程师",
human_input_mode="NEVER"
)
return agent