Files
autogen/agents/qa_agent.py
2026-03-12 13:27:03 +08:00

222 lines
6.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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