新增了Twitch、Telegram、Discord、Slack、Mattermost、WeChat、Zalo等多渠道的单元测试用例,覆盖了令牌处理、速率限制、消息去重、会话解析、格式转换、安全策略等模块 同时在测试配置中添加了测试用的OpenAI API密钥环境变量
253 lines
8.3 KiB
Python
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" |