test: add unit/integration/E2E test suites, fix create_session bug, update docs

- Unit tests: test_session.py (27), test_error_kb.py (24), test_agent.py hardened
- Integration tests: test_api_integration.py (25) with FastAPI TestClient
- E2E tests: main-flows.spec.ts (8) with Playwright + API mocking
- Bug fix: backend/session.py create_session() missing session_id parameter
- Config: frontend/playwright.config.ts, npm run test:e2e
- Docs: update CLAUDE.md v9, .gitignore for test artifacts/eval reports
This commit is contained in:
2026-05-23 08:38:29 +08:00
parent b444303055
commit 1952d75f13
11 changed files with 1029 additions and 12 deletions
+9 -8
View File
@@ -44,8 +44,8 @@ class TestAcceptanceScenarios:
final = run_graph(graph, state)
assert final.get("current_jrxml"), "应该已生成 JRXML"
# 注意:通过/失败取决于 LLM 输出质量;我们检查是否得到了结果
print(f"场景 1 状态: {final.get('status')}, 错误: {final.get('error_msg', '')[:100]}")
assert final.get("status") in ("pass", "fail"), f"意外状态: {final.get('status')}"
assert "<jasperReport" in final["current_jrxml"], "输出应包含合法 JRXML 根元素"
def test_scenario2_auto_correction(self, graph):
"""场景 2:故意提出一个可能初次失败的需求。"""
@@ -58,7 +58,8 @@ class TestAcceptanceScenarios:
final = run_graph(graph, state)
assert final.get("retry_count", 0) <= 5, "不应超过最大重试次数"
print(f"场景 2 状态: {final.get('status')}, 重试次数: {final.get('retry_count', 0)}")
assert "status" in final, "最终状态应包含 status 字段"
assert final.get("current_jrxml") or final.get("error_msg"), "应有输出或错误消息"
def test_scenario3_multi_turn_modification(self, graph):
"""场景 3:多轮对话 - 先生成,再修改两次。"""
@@ -71,8 +72,8 @@ class TestAcceptanceScenarios:
state["stage"] = "initial_generation"
final = run_graph(graph, state)
print(f"第 1 轮状态: {final.get('status')}, 错误: {final.get('error_msg', '')[:100]}")
assert final.get("current_jrxml"), "第 1 轮应该已生成 JRXML"
assert final.get("status") in ("pass", "fail")
# 第 2 轮:添加月度销售汇总
state2 = final.copy()
@@ -82,8 +83,8 @@ class TestAcceptanceScenarios:
state2["retry_count"] = 0
final2 = run_graph(graph, state2)
print(f"第 2 轮状态: {final2.get('status')}")
assert final2.get("current_jrxml"), "第 2 轮应该已修改 JRXML"
assert final2.get("status") in ("pass", "fail")
# 第 3 轮:修改标题
state3 = final2.copy()
@@ -93,9 +94,9 @@ class TestAcceptanceScenarios:
state3["retry_count"] = 0
final3 = run_graph(graph, state3)
print(f"第 3 轮状态: {final3.get('status')}")
jrxml = final3.get("current_jrxml", "")
assert "2024" in jrxml or "Annual" in jrxml, "标题修改应该体现在 JRXML 中"
assert final3.get("status") in ("pass", "fail")
def test_scenario4_context_aware_modification(self, graph):
"""场景 4:基于对话上下文的修改。"""
@@ -109,7 +110,7 @@ class TestAcceptanceScenarios:
state["stage"] = "initial_generation"
final = run_graph(graph, state)
print(f"第 1 轮状态: {final.get('status')}")
assert final.get("current_jrxml"), "第 1 轮应该已生成 JRXML"
# 第 2 轮:上下文感知修改
state2 = final.copy()
@@ -119,9 +120,9 @@ class TestAcceptanceScenarios:
state2["retry_count"] = 0
final2 = run_graph(graph, state2)
print(f"第 2 轮状态: {final2.get('status')}")
jrxml = final2.get("current_jrxml", "")
assert "isBold" in jrxml or "size=" in jrxml, "字体修改应该体现在结果中"
assert final2.get("status") in ("pass", "fail")
def test_max_retry_handling(self, graph):
"""测试在 MAX_RETRY 次失败后,图能否正常终止。"""