EvoCode 测试计划(用例级)
分层测试用例:单元 / 契约 / 集成 / 安全 / 性能 · 每个用例可执行、可验收
版本:v1.0 · 2026-08-10 · 覆盖《01 需求》AC-1~12 与《06 契约》主要端点(全端点冒烟见 §5,dependencies/quality-issues/explain/docs 用例随 P3/P4/P7 阶段补充)
使用说明:按阶段门禁(§7)执行对应用例组;用例编号 T-{层}-{序号}。回归清单为每次发版必跑项。
1. 测试分层与命令
| 层 |
端 |
工具 |
命令 |
| 单元 |
backend |
JUnit5 + Mockito |
mvn test |
| 单元 |
analyzer |
pytest |
pytest -q |
| 单元 |
frontend |
vitest(可选) |
npm run test |
| 静态 |
analyzer |
ruff + import-linter |
ruff check . && ruff format --check .、import-linter enforce |
| 静态 |
frontend |
ESLint + Prettier + tsc |
npm run lint && npm run build |
| 契约 |
三端 |
脚本(JSON schema 比对) |
scripts/check-contract.ps1 |
| 集成/冒烟 |
三端 |
手工 + curl 脚本 |
scripts/smoke.ps1 |
| 安全 |
三端 |
手工脚本 |
scripts/security-smoke.ps1 |
| 性能 |
三端 |
手工计时 + 日志 |
见 §7 |
2. 单元测试用例(backend service)
| # |
模块 |
用例 |
前置 |
预期 |
| T-U-01 |
AnalysisService |
发起分析成功 |
项目存在,无运行中任务 |
返回 PENDING 任务;幂等校验通过 |
| T-U-02 |
AnalysisService |
并发发起被拒 |
已有 RUNNING 任务 |
抛 2002;不创建新任务 |
| T-U-03 |
AnalysisService |
状态机非法转移 |
任务 FAILED |
禁止 SUCCEEDED→FAILED 等非法路径 |
| T-U-04 |
AnalysisService |
regenerate 状态转移 |
SUCCEEDED 且有报告 |
RUNNING(REPORT)→SUCCEEDED;期间重复触发 2008 |
| T-U-05 |
UploadService |
zip 路径穿越 |
zip 含 ../evil |
拒绝,2003,临时目录清理 |
| T-U-06 |
UploadService |
zip 超限 |
>200MB 或解压 >500MB |
拒绝 2003 |
| T-U-07 |
UploadService |
单层目录上移 |
zip 内仅一层目录 |
项目根为该层 |
| T-U-08 |
AnalyzerClient |
analyzer 不可达 |
未启动 |
抛 3001 |
| T-U-09 |
AnalyzerClient |
错误码映射 |
返回 LLM_NO_KEY |
触发降级路径而非异常 |
| T-U-10 |
ReportService |
LLM 成功 |
mock 返回合法 JSON |
落库 source=LLM |
| T-U-11 |
ReportService |
LLM 失败降级 |
mock 抛错 |
规则版 source=RULES,不失败 |
| T-U-12 |
ReportService |
JSON 结构校验 |
LLM 返回缺字段 |
重试一次后走规则版 |
| T-U-13 |
TechDebtService |
自动生成去重 |
同键 issue 已存在 |
不重复插入,更新时间戳 |
| T-U-14 |
TechDebtService |
状态机约束 |
OPEN→WONTFIX 无原因 |
400,拒绝 |
| T-U-15 |
TechDebtService |
复发复查 |
DONE 后新分析仍命中 |
重新 OPEN |
| T-U-16 |
FileNodeService |
快照重建 |
同 analysis_id 二次写入 |
先删后插,无堆积 |
| T-U-17 |
FileController |
content 越权 |
path=../etc/passwd |
400/2005 |
| T-U-18 |
FileController |
content 超限 |
>2MB 文件 |
400/2005 |
| T-U-19 |
ChatService |
重复发送 |
同 content 2s 内重发 |
2007 |
| T-U-20 |
ProjectService |
删除级联 |
项目含全量数据 |
各表清零 + 磁盘目录删除 |
| T-U-21 |
ProjectService |
删除中分析 |
有 RUNNING 任务 |
CANCELLED + 等待退出 + 级联 |
| T-U-22 |
工具类 |
PathSafetyUtil |
各种路径形态 |
白名单逻辑正确(含符号链接) |
| T-U-23 |
GitCloneService |
克隆成功(=AC-2) |
mock git 返回仓库 |
落库档案 + storage_path 存在 |
| T-U-24 |
GitCloneService |
私有/不存在仓库 |
模拟 git 退出码 128 |
2009,提示"不存在或为私有" |
| T-U-25 |
GitCloneService |
克隆超时 |
模拟 5min 未完成 |
2009 + 临时目录清理 |
| T-U-26 |
GitCloneService |
cloneDepth 参数 |
depth=0 全量 |
参数透传正确(FR-8.4) |
| T-U-27 |
QuickScanService |
快扫成功 |
上传完成,无运行中任务 |
分析 RUNNING(SCAN)→READY;file_node 快照替换;档案字段更新 |
| T-U-28 |
QuickScanService |
快扫幂等/重复触发 |
已有快扫任务进行中 |
不重复创建任务(2002/复用现有),不双写 file_node |
3. 单元测试用例(analyzer)
| # |
模块 |
用例 |
前置 |
预期 |
| T-A-01 |
ignore |
默认忽略规则 |
fixtures 含 node_modules/.git/dist |
全部剪枝不统计 |
| T-A-02 |
ignore |
.evocodeignore |
自定义忽略 + ! 取反 |
按规则生效 |
| T-A-03 |
langdetect |
后缀映射 |
20 种后缀样本 |
全部正确归类;未知→OTHER |
| T-A-04 |
langdetect |
Dockerfile 文件名匹配 |
Dockerfile |
识别为 Dockerfile 语言 |
| T-A-05 |
loc |
空行/注释不计 |
固定混合样本 |
与硬编码预期 LOC 一致(空行/注释/shebang 不计) |
| T-A-06 |
filescanner |
大文件保护 |
文件 > scan_max_file_bytes(默认 2MB) |
skippedBigFiles+1,不崩溃 |
| T-A-07 |
stackdetect |
pom.xml |
Spring Boot 2.5 pom |
识别 Spring Boot + Maven 标签,hasBackend=true(frameworks 无版本字段,不断言版本) |
| T-A-08 |
stackdetect |
package.json |
Vue+Electron |
识别双框架 |
| T-A-09 |
dependency |
EOL 规则命中 |
spring-boot 2.5.14 |
HIGH + is_eol=true + 建议 |
| T-A-10 |
dependency |
版本解析容错 |
异常版本字符串(1.0.0.RELEASE) |
不崩溃,LOW |
| T-A-11 |
parsers |
java 解析 |
UserService.java |
类/方法符号 + 调用关系正确 |
| T-A-12 |
parsers |
未知语言降级 |
无 parser 语言 |
返回空符号,流程继续 |
| T-A-13 |
quality |
Sonar 不可用 |
sonar 未启动 |
200 + available=false |
| T-A-14 |
evolution |
git 统计 |
fixtures 迷你 git 仓库 |
增删行/文件数/作者正确 |
| T-A-15 |
llm_client |
无 Key |
未配置 |
抛 LLMError(LLM_NO_KEY) |
| T-A-16 |
llm_client |
JSON 输出清洗 |
返回含 ```json 围栏 |
解析成功 |
| T-A-17 |
report_generator |
规则版生成 |
LLM 不可用 |
输出结构合法 + source=RULES |
| T-A-18 |
pipeline |
端点内 Step 顺序与超时 |
模拟超时 |
按序执行;超时报错含部分结果 |
| T-A-19 |
schemas |
契约字段一致性 |
导出 JSON schema |
与 backend DTO 比对通过 |
4. 契约测试
| # |
用例 |
方法 |
预期 |
| T-C-01 |
analyzer↔backend 字段一致 |
analyzer model_json_schema() 导出 vs Java DTO 反射字段 |
全字段一致(允许后端多字段) |
| T-C-02 |
错误码表一致 |
grep 错误码常量 vs 06 §2.2 |
无遗漏、无未用码(2004 预留除外) |
| T-C-03 |
SSE 事件类型 |
协议文档 vs 实现枚举 |
仅 delta/citations/done/error |
5. 集成与手工冒烟
| # |
用例 |
步骤 |
预期 |
| T-I-01a |
上传→快扫→档案(=AC-1,P1) |
上传 Chatez.zip → 快扫 → 查档案 |
3 分钟内档案字段非空(语言占比/框架/LOC/文件数),与人工统计误差 <10% |
| T-I-01b |
FULL 分析→报告全链路(=AC-3~4,P2) |
发起 FULL → 轮询 → 报告 |
12 分钟内出报告,字段完整 |
| T-I-02 |
轮询竞态(=AC-7) |
快速连发 2 次分析 |
第二次 2002 |
| T-I-03 |
无 Key 降级(=AC-6/12) |
清空 LLM_API_KEY 重跑 |
报告 source=RULES + 前端横幅 |
| T-I-04 |
删除清理(=AC-9) |
删除后查库与磁盘 |
无残留 |
| T-I-05 |
恶意 zip(=AC-8) |
构造恶意 zip |
2003,服务不崩 |
| T-I-06 |
空项目(=AC-11) |
上传无源码 zip |
"疑似无源码"提示(判定:scan fileCount==0) |
| T-I-07 |
content 接口(P0-3) |
正常读 + 越权读 |
正常返回 / 400-2005 |
| T-I-08 |
regenerate(P2) |
重生成报告 |
新报告覆盖,regeneratedAt 更新 |
| T-I-09 |
会话增删(P6) |
建会话→发消息→删会话 |
全链路 + 级联删消息 |
| T-I-10 |
SSE 断线(P6) |
流中断线后重发 |
重发成功,无重复落库 |
| T-I-11 |
服务重启恢复 |
分析中重启 backend |
任务 FAILED("服务重启中断"),可重发 |
| T-I-12 |
删除中分析(P2-5) |
分析中删除项目 |
CANCELLED + 级联清理 |
| T-I-13 |
GitHub 创建全链路(=AC-2) |
输入公开仓库 → 档案 |
克隆成功 + 档案字段非空 |
| T-I-14 |
大文件 zip(=AC-10) |
上传含 5MB 单文件的 zip → 快扫 → 查档案 |
档案 skippedBigFiles≥1,扫描不卡死,详情注明跳过 |
6. 安全测试
| # |
用例 |
步骤 |
预期 |
| T-S-01 |
zip 路径穿越/符号链接 |
构造含 ../、绝对路径、symlink 的 zip |
全部拒绝,记录安全日志 |
| T-S-02 |
文件内容越权 |
../、绝对路径、未注册路径 |
400/2005 |
| T-S-03 |
二进制探测 |
content 接口读二进制 |
拒绝 |
| T-S-04 |
日志脱敏 |
跑全链路后 grep 日志 |
无 Key、无文件全文 |
| T-S-05 |
无执行路径 |
grep analyzer 代码 |
无 eval/exec/subprocess 非白名单调用 |
| T-S-06 |
git 参数注入 |
evolution 请求注入特殊参数 |
白名单拦截,不执行 |
| T-S-07 |
排序注入 |
sort=malicious |
1002 |
| T-S-08 |
端口暴露 |
netstat 检查 |
8091/5432/9000 仅 127.0.0.1 |
7. 性能测试(预算见《开发指导》§14)
| # |
用例 |
样本 |
预算 |
方法 |
| T-P-01 |
扫描耗时(=AC-5) |
2 万行项目 |
≤10min |
日志时间戳 |
| T-P-02 |
LLM 报告 |
— |
≤120s(含重试) |
日志 |
| T-P-03 |
列表接口 |
20 个项目 |
≤1s |
curl 计时 |
| T-P-04 |
并发 3 任务 |
3 项目同时分析 |
队列不丢任务 |
观察 PENDING 排队 |
| T-P-05 |
架构图加载 |
3000+ 节点 |
≤3s |
前端计时 |
8. 阶段门禁(哪个阶段验收哪些用例)
| 阶段 |
必过用例 |
说明 |
| P1 |
T-U-05/06/07/17/18/22/23/24/25/26/27/28、T-A-01~08、T-I-01a/05/06/13/14、T-C-01 |
档案闭环 + 安全基础(对应 AC-1/2/8/10/11) |
| P2(v0.1) |
全部 §2/§3 + T-I-01b/02/03/04/05/06/13/14 + T-P-01~03 + 安全全过 |
12 AC 全通过 |
| P3 |
T-A-09/10/13/15、T-U-09/10/11/12 |
质量 + 降级 |
| P4 |
T-A-11/12/18、T-P-05 |
架构 + 解析器 |
| P5 |
T-A-14、T-U-15 相关、T-I-12 |
演化 + 热点落库 |
| P6 |
T-U-19、T-I-09/10、T-C-03 |
聊天 + SSE |
| P7 |
T-U-13/14、T-C-02 |
技术债闭环 |
每次发版回归(必跑):T-U-02/05/23、T-A-01/03、T-I-01/03/05、T-S-01/04、T-P-01(高频冒烟 7 项,对应 AC-1/2/3/5/6/7/8/9,与 01 §13 / 02 §13 口径一致)。
9. 测试数据准备
| 数据 |
用途 |
位置 |
samples/chatez-demo.zip |
主演示项目(2 万行级,含多语言) |
samples/(入库) |
tests/fixtures/ |
analyzer 单测小样本(<50 文件;T-A-01~08 用例内用 tmp_path 动态构造,清单见各用例) |
analyzer/tests/fixtures/ |
tests/fixtures/malicious.zip |
路径穿越样本 |
analyzer/tests/fixtures/ |
tests/fixtures/mini-git |
git 统计样本(预置 20 commits) |
analyzer/tests/fixtures/ |
tests/fixtures/llm_stub.py |
LLM mock 固定输出 |
analyzer/tests/ |
| mock LLM 响应 JSON |
报告/解释固定样例 |
backend/src/test/resources/ |
10. 测试报告要求(答辩素材)
- 每次 v0.x 里程碑跑完整门禁,产出
docs/screenshots/ 截图 + docs/devlog 记录
- 性能数据汇总表(T-P 系列)单独成文,论文"系统验证"章节直接引用