ForcePilot/backend/test/unit/channels/test_msteams_analysis.py
Kris 3264900bc9 test: 新增多渠道单元测试用例并配置测试环境变量
新增了Twitch、Telegram、Discord、Slack、Mattermost、WeChat、Zalo等多渠道的单元测试用例,覆盖了令牌处理、速率限制、消息去重、会话解析、格式转换、安全策略等模块
同时在测试配置中添加了测试用的OpenAI API密钥环境变量
2026-05-12 00:56:47 +08:00

253 lines
8.3 KiB
Python

from __future__ import annotations
import pytest
from yuxi.channels.adapters.msteams.analysis.researchers import (
WebResearchAgent,
CodeFeatureAgent,
CodeIssueAgent,
)
from yuxi.channels.adapters.msteams.analysis.reporter import (
AnalysisReporter,
FixImplementer,
)
from yuxi.channels.adapters.msteams.analysis.graph import AnalysisGraph
from yuxi.channels.adapters.msteams.analysis.state import AnalysisState
class TestWebResearchAgent:
@pytest.fixture
def agent(self):
return WebResearchAgent()
@pytest.mark.asyncio
async def test_research_returns_non_empty_result(self, agent):
result = await agent.research("", {})
assert result
assert len(result) > 100
@pytest.mark.asyncio
async def test_result_contains_bot_framework_section(self, agent):
result = await agent.research("", {})
assert "Bot Framework" in result
@pytest.mark.asyncio
async def test_result_contains_best_practices(self, agent):
result = await agent.research("", {})
assert "最佳实践" in result
@pytest.mark.asyncio
async def test_result_contains_similar_adapters(self, agent):
result = await agent.research("", {})
assert "同类适配器" in result
@pytest.mark.asyncio
async def test_result_contains_api_standards(self, agent):
result = await agent.research("", {})
assert "API 标准" in result
class TestCodeFeatureAgent:
@pytest.fixture
def agent(self):
return CodeFeatureAgent()
@pytest.mark.asyncio
async def test_research_returns_non_empty_result(self, agent):
result = await agent.research("", {})
assert result
assert len(result) > 100
@pytest.mark.asyncio
async def test_result_contains_architecture(self, agent):
result = await agent.research("", {})
assert "架构" in result
@pytest.mark.asyncio
async def test_result_contains_data_flow(self, agent):
result = await agent.research("", {})
assert "数据流" in result
@pytest.mark.asyncio
async def test_result_contains_interface_analysis(self, agent):
result = await agent.research("", {})
assert "接口" in result
@pytest.mark.asyncio
async def test_result_contains_module_interactions(self, agent):
result = await agent.research("", {})
assert "模块" in result
class TestCodeIssueAgent:
@pytest.fixture
def agent(self):
return CodeIssueAgent()
@pytest.mark.asyncio
async def test_research_returns_non_empty_result(self, agent):
result = await agent.research("", {})
assert result
assert len(result) > 100
@pytest.mark.asyncio
async def test_result_contains_critical_bugs(self, agent):
result = await agent.research("", {})
assert "BUG-001" in result or "关键 Bug" in result
@pytest.mark.asyncio
async def test_result_contains_error_handling(self, agent):
result = await agent.research("", {})
assert "错误处理" in result
@pytest.mark.asyncio
async def test_result_contains_security_issues(self, agent):
result = await agent.research("", {})
assert "安全" in result
@pytest.mark.asyncio
async def test_result_contains_performance_issues(self, agent):
result = await agent.research("", {})
assert "性能" in result
@pytest.mark.asyncio
async def test_result_contains_code_quality(self, agent):
result = await agent.research("", {})
assert "代码质量" in result
class TestAnalysisReporter:
@pytest.fixture
def reporter(self):
return AnalysisReporter()
@pytest.mark.asyncio
async def test_generate_deficiency_report_non_empty(self, reporter):
report = await reporter.generate_deficiency_report("web", "feature", "issue")
assert report
assert len(report) > 100
@pytest.mark.asyncio
async def test_report_contains_executive_summary(self, reporter):
report = await reporter.generate_deficiency_report("web", "feature", "issue")
assert "执行摘要" in report
@pytest.mark.asyncio
async def test_report_contains_missing_features(self, reporter):
report = await reporter.generate_deficiency_report("web", "feature", "issue")
assert "缺失的核心功能" in report
@pytest.mark.asyncio
async def test_report_contains_gap_analysis(self, reporter):
report = await reporter.generate_deficiency_report("web", "feature", "issue")
assert "与行业标准的差距" in report
@pytest.mark.asyncio
async def test_report_contains_fix_priority(self, reporter):
report = await reporter.generate_deficiency_report("web", "feature", "issue")
assert "P0" in report
@pytest.mark.asyncio
async def test_generate_fix_plan_non_empty(self, reporter):
plan = await reporter.generate_fix_plan("report", "issue")
assert plan
assert len(plan) > 100
@pytest.mark.asyncio
async def test_fix_plan_contains_specific_fixes(self, reporter):
plan = await reporter.generate_fix_plan("report", "issue")
assert "FIX-001" in plan
assert "FIX-002" in plan
assert "FIX-003" in plan
class TestFixImplementer:
@pytest.fixture
def fixer(self):
return FixImplementer()
@pytest.mark.asyncio
async def test_implement_returns_fix_list(self, fixer):
results = await fixer.implement("plan", {})
assert isinstance(results, list)
assert len(results) >= 5
@pytest.mark.asyncio
async def test_each_fix_has_required_fields(self, fixer):
results = await fixer.implement("plan", {})
for item in results:
assert "fix_id" in item
assert "file" in item
assert "description" in item
assert "status" in item
@pytest.mark.asyncio
async def test_all_fixes_pending(self, fixer):
results = await fixer.implement("plan", {})
for item in results:
assert item["status"] == "pending_implementation"
class TestAnalysisGraph:
@pytest.fixture
def graph(self):
return AnalysisGraph()
@pytest.fixture
def sample_module_files(self):
return {
"adapter.py": "fake adapter content",
"send.py": "fake send content",
}
@pytest.mark.asyncio
async def test_run_completes_successfully(self, graph, sample_module_files):
state = await graph.run("/fake/path", sample_module_files)
assert isinstance(state, dict)
assert "web_research_result" in state
assert "code_feature_result" in state
assert "code_issue_result" in state
assert "deficiency_report" in state
assert "fix_plan" in state
assert "fix_results" in state
@pytest.mark.asyncio
async def test_run_and_get_report_returns_string(self, graph, sample_module_files):
report = await graph.run_and_get_report("/fake/path", sample_module_files)
assert isinstance(report, str)
assert len(report) > 500
@pytest.mark.asyncio
async def test_run_and_get_report_contains_all_sections(self, graph, sample_module_files):
report = await graph.run_and_get_report("/fake/path", sample_module_files)
assert "Bot Framework" in report
assert "架构" in report
assert "BUG-001" in report or "关键 Bug" in report
assert "缺失的核心功能" in report
assert "FIX-001" in report
class TestAnalysisState:
def test_state_creation_empty(self):
state: AnalysisState = {}
assert isinstance(state, dict)
def test_state_with_module_path(self):
state: AnalysisState = {"module_path": "/test/path"}
assert state["module_path"] == "/test/path"
def test_state_with_all_fields(self):
state: AnalysisState = {
"module_path": "/test",
"module_files": {"a.py": "content"},
"web_research_result": "web",
"code_feature_result": "feature",
"code_issue_result": "issue",
"deficiency_report": "report",
"fix_plan": "plan",
"fix_results": [{"id": "1"}],
"error": "some error",
}
assert state["module_path"] == "/test"
assert state["fix_results"] == [{"id": "1"}]
assert state["error"] == "some error"