增强测试系统 — 全面测试计划 v3.0
日期: 2026-06-19 | 対象: feat/enhanced-test-phase1 / main
測試范围: 全模块 34/36 + web API/Worker | 7 维度 | ~518 testing points
测试策略
覆盖原则
- Boil the Lake: AI 使完整性成本趋近于零,推荐完整覆盖而非 happy path
- 按风险优先级: 管道中枢 > 外部依赖调用 > 数据模型 > 辅助工具
- 维度: 功能正确性 / 错误恢复 / 边界值 / 并发安全 / 性能衰减 / 安全防护 / 环境依赖
测试层次
测试手法
| 手法 |
适用层级 |
说明 |
| TDD (红绿) |
L0 |
先写测试,再实现 |
| Golden 测试 |
L2-L3 |
已知期望值对比 |
| 模糊测试 |
L1 |
异常 COBOL 输入容错 |
| 边界值分析 |
L0, L5 |
PIC 桁数边界、空值、极值 |
| 错误注入 |
L0-L1 |
LLM timeout/malformed、cobc 编译失败 |
| 降级测试 |
L1 |
gcov failure/absence 时降级确认 |
| 竞态条件 |
L5 |
并发 Worker + Task JSON 文件读写 |
| 安全审计 |
L5 |
路径遍历、类型校验、信息泄露 |
L0: 模块单元测试
0.1 cobol_testgen API (保持 + 补充)
测试文件: tests/test_cobol_testgen.py
| # |
测试名 |
内容 |
输入 |
期待输出 |
| UT-01 |
extract_structure: 空程序 |
空字符串 |
{"total_branches": 0} |
|
| UT-02 |
extract_structure: IF 1个 |
IF A > B ... ELSE ... |
branches=2, decisions=1 |
|
| UT-03 |
extract_structure: EVALUATE |
EVALUATE X WHEN 1 ... WHEN OTHER |
decisions=1, WHEN 数确认 |
|
| UT-04 |
extract_structure: 多文件 |
3文件程序 |
file_count=3 |
|
| UT-05 |
extract_structure: CALL |
CALL 'SUBPGM' |
has_call=True |
|
| UT-06 |
extract_structure: SEARCH ALL |
OCCURS+SEARCH ALL |
has_search_all=True |
|
| UT-07 |
extract_structure: 固定格式 |
7桁目代码固定格式 |
正常解析(段落数>0) |
|
| UT-08 |
extract_structure: GOBACK |
GOBACK 语句 |
非 STOP RUN 但正确退出 |
|
| UT-09 |
extract_structure: ALTER |
ALTER X TO PROCEED TO Y |
标记 alter 语句 |
|
| UT-10 |
extract_structure: ENTRY |
ENTRY 'ENTPT' |
多入口点识别 |
|
| UT-11 |
extract_structure: 无 PROCEDURE DIVISION |
数据部只有 ID/DATA |
空结构返回,不崩溃 |
|
| UT-12 |
generate_data: 正常生成 |
IF 程序 |
≥2 条数据 |
|
| UT-13 |
generate_data: 空程序 |
无分支 |
0 或 1 条 |
|
| UT-14 |
generate_data: 深嵌套 REDEFINES |
A REDEFINES B REDEFINES C |
所有变体字段正确取值 |
|
| UT-15 |
generate_data: OCCURS DEPENDING 最大 |
ODO 到达最大值 |
数组长度正确 |
|
| UT-16 |
generate_data: PIC 9(18) |
超出 64-bit 范围 |
不溢出,字符串表示 |
|
| UT-17 |
generate_data: SIGN LEADING/TRAILING SEPARATE |
SIGN IS LEADING SEPARATE |
符号位正确 |
|
| UT-18 |
incremental_supplement: 差分 |
未覆盖 ID 指定 |
对应 ID 数据 |
|
| UT-19 |
incremental_supplement: 不存在 ID |
[-1] |
空列表 |
|
| UT-20 |
check_coverage: 静态报告 |
structure 仅 |
"note" 含静态限制描述 |
|
0.2 cobol_testgen cond (新增)
测试文件: tests/cobol_testgen/test_cond.py
| # |
测试名 |
内容 |
期待 |
| CO-01 |
parse_single_condition: 数值比较 |
A > 100 |
CondLeaf(> 100) |
| CO-02 |
parse_single_condition: 文字列 |
B = 'Y' |
CondLeaf(= 'Y') |
| CO-03 |
parse_compound: AND |
A > 0 AND B < 5 |
CondAnd(>0, <5) |
| CO-04 |
parse_compound: OR |
A = 1 OR B = 2 |
CondOr(=1, =2) |
| CO-05 |
parse_compound: 嵌套 AND+OR |
(A > 0 AND B < 5) OR C = 1 |
正确优先级 |
| CO-06 |
mcdc_sets: IF |
IF A > 100 |
2 sets |
| CO-07 |
mcdc_sets: AND |
A > 0 AND B < 5 |
3 sets (MCDC) |
| CO-08 |
mcdc_sets: OR |
A = 1 OR B = 2 |
3 sets (MCDC) |
| CO-09 |
evaluate_tree: 真路径 |
A=200 当 A>100 |
True |
| CO-10 |
evaluate_tree: 假路径 |
A=50 当 A>100 |
False |
0.3 cobol_testgen core (新增)
测试文件: tests/cobol_testgen/test_core.py
| # |
测试名 |
内容 |
期待 |
| CE-01 |
scan_paragraphs: 正常 |
3段落 |
3个段落 |
| CE-02 |
scan_paragraphs: 空程序 |
无段落 |
空列表 |
| CE-03 |
build_branch_tree: IF |
IF 语句 |
BrIf 节点 |
| CE-04 |
build_branch_tree: EVALUATE |
EVALUATE 语句 |
BrEval 节点 |
| CE-05 |
build_branch_tree: PERFORM |
PERFORM VARYING |
BrPerform 含循环 |
| CE-06 |
build_branch_tree: SEARCH ALL |
SEARCH ALL |
BrSearch 节点 |
| CE-07 |
classify_field_roles: IO / WORKING / LINKAGE |
IO / WORKING / LINKAGE 字段 |
正确角色分类 |
| CE-08 |
propagate_assignments: 嵌套组 |
子字段赋值传播 |
子字段继承值 |
| CE-09 |
propagate_assignments: REDEFINES |
REDEFINES 字段赋值 |
共享起始位置 |
0.4 cobol_testgen coverage (新增)
测试文件: tests/cobol_testgen/test_coverage.py
| # |
测试名 |
内容 |
期待 |
| CV-01 |
collect_decision_points: IF |
1个 IF |
1个决策点 (2分支) |
| CV-02 |
collect_decision_points: EVALUATE |
EVALUATE 4 WHEN |
1决策点 4分支 |
| CV-03 |
collect_decision_points: SEARCH ALL |
SEARCH ALL |
1决策点 |
| CV-04 |
mark_coverage: 全覆盖 |
所有分支有测试数据 |
覆盖率 100% |
| CV-05 |
mark_coverage: 部分覆盖 |
一半分支有数据 |
覆盖率 50% |
| CV-06 |
mark_coverage: 零覆盖 |
无测试数据 |
覆盖率 0% |
| CV-07 |
locate_decision_lines: 源码定位 |
已知决策点 |
正确行号 |
| CV-08 |
generate_html_report: 基本渲染 |
决策点+统计 |
有效 HTML |
0.5 cobol_testgen design (新增)
测试文件: tests/cobol_testgen/test_design.py
| # |
测试名 |
内容 |
期待 |
| DE-01 |
enum_paths: 2层嵌套 |
IF 内 IF |
路径枚举数正确 |
| DE-02 |
apply_constraint: 数值约束 |
field > 100 |
字段值 > 100 |
| DE-03 |
apply_constraint: 文字约束 |
field = 'ABC' |
字段值 'ABC' |
| DE-04 |
apply_constraint: MCDC 约束 |
AND 条件 |
满足指定真值 |
| DE-05 |
generate_records: 基本 |
已知分支路径 |
记录字段值正确 |
| DE-06 |
sync_redefined_fields: REDEFINES |
REDEFINES 字段 |
同步后值一致 |
| DE-07 |
apply_occurs_depending: ODO |
OCCURS DEPENDING ON |
数组长度按依赖字段 |
| DE-08 |
make_base_record: 序列值 |
seq_num=1 |
字段含序列值 |
0.6 cobol_testgen read (新增)
测试文件: tests/cobol_testgen/test_read.py
| # |
测试名 |
内容 |
期待 |
| RD-01 |
preprocess: 固定格式 |
7桁目代码 |
正确提取 |
| RD-02 |
preprocess: 自由格式 |
>>SOURCE FORMAT IS FREE |
正确提取 |
| RD-03 |
preprocess: COPY 展开 |
COPY CPYBOOK |
COPY 内容展开 |
| RD-04 |
preprocess: 嵌套 COPY |
COPY 内含 COPY |
递归展开 |
| RD-05 |
extract_data_division: 多段 |
ID/DATA/PROCEDURE |
DATA DIVISION 文本 |
| RD-06 |
parse_pic: 简单 |
PIC 9(4) |
PicInfo(4, 0) |
| RD-07 |
parse_pic: 带小数 |
PIC S9(7)V99 |
PicInfo(9, 2, signed) |
| RD-08 |
parse_pic: COMP-3 |
PIC S9(7)V99 COMP-3 |
signed, COMP-3 |
| RD-09 |
parse_data_division: 层级 |
01/05/10/15 |
正确层级树 |
| RD-10 |
parse_data_division: 88-level |
88 AA VALUE 'X' |
is_88 识别 |
| RD-11 |
parse_data_division: REDEFINES |
字段含 REDEFINES |
redefines 属性 |
| RD-12 |
parse_data_division: OCCURS |
OCCURS 10 TIMES |
occurs=10 |
| RD-13 |
resolve_copybooks: 多路径 |
搜索多目录 |
找到 COPY |
0.7 cobol_testgen output (新增)
测试文件: tests/cobol_testgen/test_output.py
| # |
测试名 |
内容 |
期待 |
| OU-01 |
output_json: 基本 |
3条测试记录 |
有效 JSON 文件 |
| OU-02 |
output_input_files: 多方向 |
I-O / INPUT 字段 |
文件输出正确 |
0.8 HINA Classifier (保持)
测试文件: tests/hina/test_classifier.py
| # |
测试名 |
内容 |
输入 |
期待 |
| HC-01 |
L1: DB操作 |
EXEC SQL SELECT |
category="DB操作" ≥90% |
|
| HC-02 |
L1: 子程序调用 |
CALL ... LINKAGE SECTION |
category="子程序调用" ≥90% |
|
| HC-03 |
L1: SORT |
SORT WORK-FILE ON KEY |
category="SORT" ≥90% |
|
| HC-04 |
L1: IS INITIAL |
PROGRAM-ID. X IS INITIAL. |
category="IS INITIAL" ≥90% |
|
| HC-05 |
L1: 编辑输出 |
WRITE AFTER ADVANCING |
category="编辑输出" ≥80% |
|
| HC-06 |
L1: 文件编成 |
ORGANIZATION IS |
category="文件编成" ≥90% |
|
| HC-07 |
关键字重叠 |
DB操作+CALL 两者 |
最大确信度关键字胜出 |
|
| HC-08 |
compute_confidence: L1≥90% |
L1 仅 |
method="keyword" |
|
| HC-09 |
compute_confidence: LLM结果 |
LLM 结果 |
method="hybrid" |
|
| HC-10 |
compute_confidence: 两者无 |
关键字无+LLM无 |
category="unknown" confidence=0 |
|
0.9 HINA Strategy (保持)
测试文件: tests/hina/test_strategy.py
| # |
测试名 |
内容 |
期待 |
| HS-01 |
get_strategy: マッチング |
9 required items |
|
| HS-02 |
get_strategy: キーブレイク |
6 required items |
|
| HS-03 |
get_strategy: 条件分岐 |
4 required items |
|
| HS-04 |
get_strategy: 未知类型 |
空模板 |
|
| HS-05 |
supplement: マーカー追加 |
マーカーレコード含む list |
|
| HS-06 |
supplement_only: 特定间隙 |
指定 ID のみマーカー |
|
0.10 HINA Gate (保持)
测试文件: tests/hina/test_gate.py
| # |
测试名 |
内容 |
输入 |
期待 |
| QG-01 |
全通过 |
branch≥95%, paragraph=100% |
passed=True |
|
| QG-02 |
分岐不足 |
branch=80% |
passed=False, decision_gaps 有 |
|
| QG-03 |
段落不足 |
paragraph=0.5 |
passed=False |
|
| QG-04 |
数据无 |
empty list |
passed=False, no_data=True |
|
| QG-05 |
评分计算 |
branch=0.92, para=1.0 |
score=0.976 |
|
0.11 HINA Retry (保持 + 补充)
测试文件: tests/hina/test_retry.py
| # |
测试名 |
内容 |
期待 |
| RH-01 |
即时 PASS |
1次 PASS |
heal=0, simple=0 |
| RH-02 |
heal 恢复 |
BLOCKED→环境修复→PASS |
heal=1, simple=0 |
| RH-03 |
simple 恢复 |
BLOCKED→重试→PASS |
heal=0, simple=1 |
| RH-04 |
上限超限 |
全部 FAIL |
status=FATAL |
| RH-05 |
QUALITY_WARN 不需重试 |
QUALITY_WARN→立即返回 |
heal=0, simple=0 |
| RH-06 |
heal 环境修复失败 |
heal 尝试仍然 BLOCKED |
simple 回退 |
| RH-07 |
并发重试计数 |
同时 heal + simple |
计数不竞争 |
0.12 HINA gcov_collector (新增)
测试文件: tests/hina/test_gcov_collector.py
| # |
测试名 |
内容 |
期待 |
| GC-01 |
collect_gcov: cobc 未安装 |
无 cobc 命令 |
available=False, reason=cobc_not_found |
| GC-02 |
collect_gcov: .gcda/.gcno 不存在 |
工作目录无覆盖文件 |
available=False, reason=no_coverage_data |
| GC-03 |
collect_gcov: 正常 |
有效 .gcda/.gcno |
available=True, line_rate>0 |
0.13 HINA Agent (LLM 分类) (补充)
测试文件: tests/hina/test_agent.py
| # |
测试名 |
内容 |
期待 |
| HA-01 |
classify_with_llm: 正常 |
有效结构体 |
返回 dict 含 category |
| HA-02 |
classify_with_llm: LLM 返回非法 JSON |
LLM 返回乱码 |
fallback 分类 |
| HA-03 |
classify_with_llm: LLM 返回空字符串 |
LLM 返回 "" |
fallback 分类 |
| HA-04 |
classify_with_llm: LLM 超时 |
httpx.TimeoutException |
fallback + 日志输出 |
| HA-05 |
_parse_llm_response: 合法 JSON |
{"category": "DB操作"} |
解析成功 |
| HA-06 |
_parse_llm_response: 非法 JSON |
"暂无" |
try/except 不崩溃 |
| HA-07 |
_parse_llm_response: 含 markdown 包裹 |
```json ... ``` |
正确提取 JSON |
| HA-08 |
_fallback_classification: 纯 DB |
EXEC SQL 无其他 |
"DB操作" |
| HA-09 |
_fallback_classification: 纯 CALL |
CALL 无 SQL |
"子程序调用" |
| HA-10 |
_fallback_classification: 两者无 |
无关键字匹配 |
"unknown" |
0.14 orchestrator (新增 — 🔥 高风险)
测试文件: tests/test_orchestrator.py
| # |
测试名 |
内容 |
期待 |
| OR-01 |
run_pipeline: 正常路径 |
所有组件正常工作 |
VerificationRun 返回, status=PASS |
| OR-02 |
run_pipeline: cobol_testgen 返回空 |
extract_structure 空 |
pipeline 继续, 适当错误 |
| OR-03 |
run_pipeline: HINA Agent 异常 |
classify_with_llm 抛出 |
不阻断 pipeline, 日志记录 |
| OR-04 |
run_pipeline: quality gate 失败 |
覆盖率不足 |
QUALITY_WARN 设置 |
| OR-05 |
run_pipeline: gcov 不可用 |
collect_gcov 失败 |
available=False, pipeline 继续 |
| OR-06 |
run_pipeline: Java 编译失败 |
mvn 返回非零 |
status=BLOCKED, exit_code≠0 |
| OR-07 |
run_pipeline: cobc 编译失败 |
cobc 返回非零 |
status=BLOCKED |
| OR-08 |
run_pipeline: Runner 运行失败 |
run() 返回非零 |
status=BLOCKED |
| OR-09 |
run_pipeline: LLM 全部回退 |
Agent1/2/3 全部 fallback |
无崩溃, 结果含 fallback 标记 |
| OR-10 |
run_pipeline: 无 LLM API key |
环境变量不存在 |
Agent1/2/3 使用默认值/failback |
| OR-11 |
run_pipeline: 大文件 (10000行 COBOL) |
大型输入文件 |
30秒内完成, 不超时 |
| OR-12 |
_done: 正常结束 |
标准 VerificationRun |
正确写入 report_path |
0.15 web/api.py (新增 — 🔥 高风险)
测试文件: tests/web/test_api.py
| # |
测试名 |
内容 |
期待 |
| WA-01 |
GET / 返回 HTML |
无参数 |
200, Content-Type text/html |
| WA-02 |
POST /verify 正常上传 |
4个文件 + runner= native |
202, 含 task_id, status=queued |
| WA-03 |
POST /verify 文件超 10MB |
超大文件 |
413 |
| WA-04 |
POST /verify 缺少文件 |
3个文件 |
422 或 400 |
| WA-05 |
POST /verify runner=spark |
spark 模式 |
202, runner=spark |
| WA-06 |
GET /status 存在任务 |
有效 task_id |
200, 含 status |
| WA-07 |
GET /status 不存在 |
无效 task_id |
404 |
| WA-08 |
GET /status 任务完成 |
结果已写入 |
status=done, fields 含数据 |
| WA-09 |
GET /fields 正常 |
有效 task_id |
200, 字段列表 |
| WA-10 |
GET /fields 任务不存在 |
无效 task_id |
404 |
| WA-11 |
GET / 表单元素存在 |
渲染检查 |
5 个文件/输入元素 |
| WA-12 |
路径遍历防护 |
../../../etc/passwd 文件上传 |
拒绝或 sanitize |
0.16 web/worker.py (新增 — 🔥 高风险)
测试文件: tests/web/test_worker.py
| # |
测试名 |
内容 |
期待 |
| WR-01 |
main: 无任务 |
空 tasks/ 目录 |
无操作, 继续循环 |
| WR-02 |
main: 正常任务 |
queued 任务文件 |
处理, 状态→done |
| WR-03 |
main: 任务文件损坏 |
非法 JSON |
异常处理, 不崩溃 |
| WR-04 |
main: runner=spark 但无 spark-submit |
spark-submit 不在 PATH |
状态→blocked, 含 reason |
| WR-05 |
main: 并发任务 |
2个 queued 任务 |
依次处理, 各有结果 |
| WR-06 |
main: Worker 中断恢复 |
running 状态→重启 Worker |
running 任务可重新处理 |
| WR-07 |
Task 文件状态机 |
queued→running→done 转换 |
状态不可逆 |
0.17 agents 模块 (新增)
测试文件: tests/agents/test_agents.py
| # |
测试名 |
内容 |
期待 |
| AG-01 |
LLMClient.call: 正常 |
消息列表 |
返回响应字符串 |
| AG-02 |
LLMClient.call: 缓存命中 |
相同消息两次调用 |
第二次返回缓存, 不调 API |
| AG-03 |
LLMClient.call: 超时 |
httpx 超时 |
抛出异常 |
| AG-04 |
LLMClient.call: 重试成功 |
首次 500, 重试 200 |
最终成功返回 |
| AG-05 |
LLMClient.call: 重试耗尽 |
全部失败 |
抛出异常 |
| AG-06 |
Agent1Parser.parse: 正常 COPYBOOK |
合法字段列表 |
返回 FieldTree, 字段数正确 |
| AG-07 |
Agent1Parser.parse: LLM 返回非法 JSON |
LLM 返回 not json |
返回 FieldTree(copybook_name="parse_error") |
| AG-08 |
Agent1Parser.parse: JSON 缺失 fields |
{} |
空 FieldTree, 不崩溃 |
| AG-09 |
Agent2Data.design: 正常 |
已知 FieldTree |
TestSuite 含测试 case |
| AG-10 |
Agent2Data.design: LLM 返回非法 |
LLM 异常 |
返回 TestSuite 含 TC-FALLBACK |
| AG-11 |
Agent2Data.design: spark_mode |
spark=True |
SparkConfig 生成 |
| AG-12 |
Agent3Diagnostic.analyze: 正常 |
FieldResult MISMATCH |
返回诊断字符串 |
0.18 config (新增)
测试文件: tests/config/test_config.py
| # |
测试名 |
内容 |
期待 |
| CF-01 |
Config: 默认值 |
无参数 |
runner_mode=native, llm_model=gpt-4o-mini |
| CF-02 |
Config: from_toml |
有效 TOML 文件 |
正确解析 |
| CF-03 |
Config: from_toml 文件不存在 |
不存在路径 |
默认值 |
| CF-04 |
Config: from_toml 非法 TOML |
格式错误 |
妥善处理/不崩溃 |
| CF-05 |
MappingConfig: 正常 |
有效 YAML 映射 |
FieldMapping 列表 |
| CF-06 |
MappingConfig: 空映射 |
空 YAML |
空列表 |
| CF-07 |
MappingConfig: 格式错误 |
非法 YAML |
解析错误处理 |
0.19 runners (新增)
测试文件: tests/runners/test_runners.py
| # |
测试名 |
内容 |
期待 |
| RN-01 |
Runner 抽象类 |
实例化 |
TypeError (抽象) |
| RN-02 |
NativeJavaRunner.compile: 成功 |
mvn 成功 |
BuildResult(success=True) |
| RN-03 |
NativeJavaRunner.compile: Maven 失败 |
mvn 非零退出 |
BuildResult(success=False) |
| RN-04 |
NativeJavaRunner.run: 正常 |
jar 输出 JSON |
RunResult(records 含数据) |
| RN-05 |
NativeJavaRunner.run: 无输出 |
jar 输出空 |
RunResult(records=[]) |
| RN-06 |
CobolRunner.compile: 成功 |
cobc 成功 |
BuildResult(success=True) |
| RN-07 |
CobolRunner.compile: 编译错误 |
cobc 语法错误 |
BuildResult(success=False) |
| RN-08 |
CobolRunner.compile: gcov 参数 |
gcov=True |
含 -fprofile-arcs 参数 |
| RN-09 |
CobolRunner.run: 正常 |
二进制执行 |
RunResult(success=True) |
| RN-10 |
DataWriter.write: 正常 |
TestSuite 数据 |
文件写入正确 |
0.20 jcl (新增)
测试文件: tests/jcl/test_jcl.py
| # |
测试名 |
内容 |
期待 |
| JC-01 |
parse_jcl: 基本 JOB |
JOB + 2 STEP |
1个 Job, 2个 JobStep |
| JC-02 |
parse_jcl: COND 参数 |
COND=(0,NE) |
CondParam(0, NE) |
| JC-03 |
parse_jcl: DD 语句 |
DD DSN=..., DISP=SHR |
DDEntry 含 DSN/DISP |
| JC-04 |
parse_jcl: 续行 |
多行 DD 语句 |
合并为单行 |
| JC-05 |
parse_jcl: 空文件 |
无内容 |
返回 None |
| JC-06 |
parse_jcl: 注释行 |
//* COMMENT |
跳过注释 |
| JC-07 |
parse_jcl: 文件不存在 |
无效路径 |
返回 None |
| JC-08 |
JclExecutor.execute: 正常 |
已解析 Job |
执行结果 |
0.21 quality (新增)
测试文件: tests/quality/test_quality.py
| # |
测试名 |
内容 |
期待 |
| QL-01 |
L1OffsetValidator.validate: cobc 存在 |
有效 FieldTree |
含 score/mismatches |
| QL-02 |
L1OffsetValidator.validate: cobc 不存在 |
无 cobc |
异常或 fallback |
| QL-03 |
L2RoundtripValidator.validate: 无 COMP-3 |
无 COMP-3 字段 |
pass=True, results=[] |
| QL-04 |
L2RoundtripValidator.validate: 有 COMP-3 |
含 COMP-3 字段 |
pass=True, 字段值正确 |
0.22 storage (新增)
测试文件: tests/storage/test_storage.py
| # |
测试名 |
内容 |
期待 |
| ST-01 |
DiskCache.get/set: 正常 |
key-value 存取 |
获取与设置一致 |
| ST-02 |
DiskCache.get: 不存在 |
无缓存 key |
返回 None |
| ST-03 |
ReportStore.save_history: 正常 |
JSONL 写入 |
追加文件 |
| ST-04 |
TestDataBundle: 路径 |
base_path |
cobol_input/spark_input 正确 |
0.23 preprocessor (新增)
测试文件: tests/test_preprocessor.py
| # |
测试名 |
内容 |
期待 |
| PP-01 |
expand: 有 COPY 文件 |
COPY CPYBOOK → 文件存在 |
COPYBOOK 内容展开 |
| PP-02 |
expand: 无 COPY 文件 |
COPY NOTEXIST |
"NOT FOUND" 标记 |
| PP-03 |
expand: 无 COPY 语句 |
纯文本 |
原文不变 |
0.24 数据模型 (补充断言)
测试文件: tests/data/test_models.py
| # |
测试名 |
内容 |
期待 |
| DM-01 |
Field 构建 |
所有属性 |
属性值正确 |
| DM-02 |
FieldTree.flatten: 嵌套 |
层级字段 |
展平字典含所有字段 |
| DM-03 |
FieldTree.flatten: 同名字段 |
不同层级同名 |
后覆盖前 |
| DM-04 |
VerificationRun: 默认 timestamp |
空构造 |
timestamp 自动填充 |
| DM-05 |
VerificationRun.verdict: PASS |
status=PASS |
"PASS" |
| DM-06 |
VerificationRun.verdict: BLOCKED |
status=BLOCKED |
"BLOCKED" |
| DM-07 |
VerificationRun.total_fields |
matched=5, mismatched=3 |
8 |
| DM-08 |
TestSuite.has_spark |
spark_config 有/无 |
True/False |
| DM-09 |
FieldResult 容忍度 |
tolerance_applied>0 |
状态含 PASS 但标记 |
0.25 报告生成器 (保持)
测试文件: tests/report/test_generator.py
| # |
测试名 |
内容 |
期待 |
| RG-01 |
generate_json: 新字段 |
VerificationRun 全字段 |
JSON 含所有字段 |
| RG-02 |
generate_html: 覆盖率显示 |
paragraph_rate>0 |
"段落覆盖率" 显示 |
| RG-03 |
generate_html: HINA 显示 |
hina_type 设置 |
"判定类型" 显示 |
| RG-04 |
generate_html: HINA 不显示 |
hina_type="" |
HINA 区不显示 |
| RG-05 |
generate_html: 质量评分显示 |
quality_score>0 |
"质量评分" 显示 |
| RG-06 |
generate_html: 质量评分不显示 |
quality_score=0 |
质量区不显示 |
| RG-07 |
generate_html: 警告显示 |
quality_warn 设置 |
警告栏显示 |
| RG-08 |
generate_machine_json: 全字段 |
VerificationRun |
branch_rate 等包含 |
| RG-09 |
generate_json: 向后兼容 |
新字段未设置 |
与现有 JSON 同结构 |
0.26 comparator (新增)
测试文件: tests/comparator/test_comparator_all.py
| # |
测试名 |
内容 |
期待 |
| CP-01 |
compare_field: 数值完全一致 |
c="100.00", j="100.00" |
status=PASS |
| CP-02 |
compare_field: 数值容忍度内 |
c="100.01", j="100.00", tol=0.02 |
status=PASS |
| CP-03 |
compare_field: 数值超出容忍 |
c="110.00", j="100.00", tol=0.02 |
status=MISMATCH |
| CP-04 |
compare_field: 日期一致 |
同日期不同格式 |
PASS |
| CP-05 |
compare_field: 字符串 |
c="ABC", j="ABC" |
PASS |
| CP-06 |
align_records: 1:1 |
COBOL 1条, Java 1条, 键匹配 |
1个对齐对 |
| CP-07 |
align_records: 多对多 |
3条+3条, 键匹配 |
3个对齐对 |
| CP-08 |
align_records: 无匹配 |
无共同键 |
空结果 |
| CP-09 |
detect_rounding: 有 rounding |
c=100, j=99.99 |
RoundingResult(detected=True) |
| CP-10 |
detect_rounding: 无 rounding |
c=100.00, j=100.00 |
RoundingResult(detected=False) |
L1: 结合测试
测试文件: tests/test_integration.py
| # |
测试名 |
场景 |
期待 |
| CT-01 |
extract→generate 一致性 |
同源 extract→generate |
generate_data 可生成数据 |
| CT-02 |
HINA→Strategy 映射 |
匹配分类→全标记生成 |
9个标记 |
| CT-03 |
QG→incremental 循环控制 |
分支不足→supplement→再检查 |
passed=True |
| CT-04 |
strategy→TestCase 型一致 |
supplement 输出→TestCase 转换 |
可作为 TestCase 使用 |
| CT-05 |
orchestrator: 正常路径 |
cobol_testgen→HINA→QG→DataWriter |
complete_tests 到 DataWriter |
| CT-06 |
orchestrator: LLM 异常 |
HINA Agent 异常 |
错误日志, pipeline 继续 |
| CT-07 |
orchestrator: gcov 无效 |
gcov_enabled=False |
动态覆盖率跳过 |
| CT-08 |
API→Worker→Orchestrator 全链路 |
POST → Worker 消费 → 结果可查 |
状态 queued→running→done |
| CT-09 |
LLM Agent 链异常回退 |
Agent1 失败 → Agent2/3 可用 |
Agent2 含 TC-FALLBACK |
| CT-10 |
Config→Runner 路由 |
runner_mode=spark → SparkJavaRunner |
正确 Runner 实例化 |
| CT-11 |
HINA+gcov→报告渲染 |
覆盖率数据 → 报告 HTML |
HTML 含覆盖率和 HINA |
| CT-12 |
JCL 解析→执行 |
parse→execute 数据流 |
执行结果 |
| CT-13 |
gcov_collector: 未安装 |
gcov 命令不存在 |
available=False |
| CT-14 |
gcov_collector: 正常 |
.gcda/.gcno 存在 |
available=True, line_rate 计算 |
| CT-15 |
Config: 质量门禁设置 |
aurak.toml 变更→from_toml |
quality_gate_mode=warn |
L2: HINA 统合测试
测试文件: test-data/run_validation.py (HINA*.cbl 10个程序)
| # |
程序 |
验证项 |
期待 |
| IT-01 |
HINA001 |
匹配结构分析 |
段落≥8, 文件≥2 |
| IT-02 |
HINA005 |
IF 分支覆盖率 |
分支≥6, 决策点≥3 |
| IT-03 |
HINA006 |
EVALUATE 覆盖率 |
分支≥6, 决策点≥3 |
| IT-04 |
HINA007 |
键中断分析 |
段落≥3, 文件≥2 |
| IT-05 |
HINA013 |
项目检查分析 |
分支≥6, 决策点≥3 |
| IT-06 |
HINA025 |
L1 分类+CALL 分析 |
HINA="子程序调用", confidence≥90% |
| IT-07 |
HINA101 |
L1 分类+SQL 分析 |
HINA="DB操作", confidence≥95% |
| IT-08 |
run_validation.py 全执行 |
所有 HINA 程序 |
8/10 pass (已知限制2) |
L3: 実 COBOL 验证
| # |
程序 |
验证项 |
期待 |
| RT-01 |
CRDVAL |
COPYBOOK 展开+全 pipeline |
无错误 |
| RT-02 |
CRDCALC |
同上 |
同上 |
| RT-03 |
CRDRPT |
同上 |
同上 |
| RT-04 |
GENDATA |
同上 |
同上 |
L4: 回归测试
| # |
测试 |
命令 |
期待 |
| RE-01 |
comparator 全测试 |
pytest tests/comparator/ -v |
22 passed |
| RE-02 |
report 全测试 |
pytest tests/report/ -v |
3 passed |
| RE-03 |
golden 全测试 |
pytest tests/test_golden.py -v |
11 passed |
| RE-04 |
e2e imports |
pytest tests/test_e2e.py -v |
1 passed |
| RE-05 |
全单元 |
pytest tests/ --ignore=e2e/ --ignore=test_web_e2e.py --ignore=test_biz_e2e.py -v |
42 passed |
L5: 非功能测试
5.1 性能
测试文件: tests/nonfunctional/test_performance.py
| # |
测试名 |
场景 |
接受标准 |
| NF-01 |
COBOL 10万行解析时间 |
extract_structure 含10万行输入 |
≤30秒完成 |
| NF-02 |
大文件上传 10MB 边界 |
POST /verify 9.5MB 文件 |
202 响应, ≤10秒 |
| NF-03 |
Worker 并发任务处理 |
5个任务同时 enqueue |
全部完成, ≤60秒 |
| NF-04 |
报告 HTML 生成:大数据集 |
1000字段结果渲染 |
≤5秒 |
| NF-05 |
LLM 调用缓存加速 |
相同请求重复调用 |
第二次 ≤100ms |
5.2 并发安全
测试文件: tests/nonfunctional/test_concurrency.py
| # |
测试名 |
场景 |
期待 |
| NF-06 |
同时 POST 相同文件 |
2个并行 /verify 请求 |
不同 task_id |
| NF-07 |
Worker 双实例 |
2个 Worker 同时 polling |
无任务重复处理 |
| NF-08 |
Task JSON 并发读写 |
读的同时 Worker 在写入 |
无损坏/无异常 |
5.3 安全
测试文件: tests/nonfunctional/test_security.py
| # |
测试名 |
场景 |
期待 |
| NF-09 |
路径遍历: 上传文件名 |
文件名 ../../../etc/passwd |
拒绝或 sanitize |
| NF-10 |
路径遍历: copybook 路径 |
--cobol-src ../../../etc/passwd |
BLOCKED |
| NF-11 |
文件类型校验 |
非 COBOL 文件扩展名 |
接受或合理处理 |
| NF-12 |
API key 环境变量未设置 |
LLM_API_KEY 为空 |
Agent 使用 fallback 而非崩溃 |
| NF-13 |
错误信息泄露 |
API 返回 stack trace |
不包含敏感路径 |
5.4 错误恢复与降级
测试文件: tests/nonfunctional/test_resilience.py
| # |
测试名 |
场景 |
期待 |
| NF-14 |
Worker 中断→重启 |
Worker 在 running 状态崩溃 |
重启后可重新处理 |
| NF-15 |
磁盘满模拟 |
task JSON 写失败 |
错误日志, 不崩溃 |
| NF-16 |
LLM API 不可用 |
网络隔离 |
Agent 全部 fallback, pipeline 继续 |
| NF-17 |
cobc 非 fatal warning |
编译通过但有 warning |
pipeline 继续, warning 记录 |
L6: E2E UI 测试 (Playwright)
测试文件: tests/test_web_e2e.py
| # |
测试名 |
场景 |
期待 |
| UI-01 |
上传页加载 |
GET / |
标题含 verify, h1 可见 |
| UI-02 |
表单元素存在 |
检查 4个文件输入 + 下拉框 |
所有元素可见, 可交互 |
| UI-03 |
文件上传 |
选择4个文件 → 提交 |
202 响应, 跳转到 /status |
| UI-04 |
上传后轮询 |
等待 Worker 完成 |
状态从 queued→done |
| UI-05 |
结果页面: 摘要 |
验证完成 |
显示 matched/mismatched |
| UI-06 |
结果页面: 字段表 |
字段列表渲染 |
每列含 name/status/COBOL/Java |
| UI-07 |
无效文件上传 |
上传非 COBOL 文件 |
合理错误提示 |
边界测试 (补充 L0-L3)
| # |
场景 |
输入 |
期待 |
| EC-01 |
空 COBOL |
IDENTIFICATION DIVISION. PROGRAM-ID. X. |
无错误 |
| EC-02 |
巨大程序 |
1万行级别 |
30秒内无超时 |
| EC-03 |
日文字符串 |
PIC N 全角数据 |
extract 正常 |
| EC-04 |
REDEFINES |
REDEFINES 使用 |
正常解析 |
| EC-05 |
OCCURS DEPENDING |
ODO 使用 |
正常解析 |
| EC-06 |
88-level 值 |
88-level 多个 |
is_88=True 识别 |
| EC-07 |
���注释 |
全行注释 |
无错误 |
| EC-08 |
非法 PIC |
PIC XXX 非标准 |
正常或合理 fallback |
| EC-09 |
空文件路径 |
--cobol-src 不存在的文件 |
BLOCKED |
| EC-10 |
Lark 语法错误 |
未预期的字符串 |
空结构, 错误日志 |
| EC-11 |
COMP-3 无效 sign nibble |
0xF 异常 nibble |
取值或报错 |
| EC-12 |
REDEFINES 链 A→B→C |
3层 REDEFINES |
所有变体可访问 |
| EC-13 |
GOBACK 对比 STOP RUN |
GOBACK 程序 |
正常退出 |
| EC-14 |
无文件上传 |
POST /verify 无任何文件 |
422 错误 |
| EC-15 |
mapping.yaml 格式错误 |
非法 YAML |
解析错误处理 |
程序类型覆盖 (33+2 COBOL 程序类型覆盖行)
| 程序类型 |
覆盖状态 |
Phase |
测试文件 |
| simple_sequential |
✅ |
Phase 7 |
tests/parametrized/test_matching.py |
| condition_heavy |
✅ |
Phase 7 |
tests/parametrized/test_matching.py |
| evaluate_driven |
✅ |
Phase 7+8 |
tests/parametrized/test_call_search.py |
| data_file_centric |
✅ |
Phase 7 |
tests/parametrized/test_matching.py |
| search_intensive |
✅ |
Phase 8 |
tests/parametrized/test_call_search.py |
| call_based |
✅ |
Phase 8 |
tests/parametrized/test_call_search.py |
| mixed_complex |
✅ |
Phase 9 |
tests/parametrized/test_crosscutting.py |
| 1:1 matching |
✅ |
Phase 7 |
tests/parametrized/test_matching.py |
| 1:N matching |
✅ |
Phase 7 |
tests/parametrized/test_matching.py |
| N:1 matching |
✅ |
Phase 7 |
tests/parametrized/test_matching.py |
| KEY break (accumulate) |
✅ |
Phase 7 |
tests/parametrized/test_matching.py |
| KEY break (aggregate) |
✅ |
Phase 7 |
tests/parametrized/test_matching.py |
| KEY break (mark) |
✅ |
Phase 7 |
tests/parametrized/test_matching.py |
| Division 50/50 |
✅ |
Phase 7 |
tests/parametrized/test_division.py |
| Division 25/25/25/25 |
✅ |
Phase 7 |
tests/parametrized/test_division.py |
| Division 100 (all) |
✅ |
Phase 7 |
tests/parametrized/test_division.py |
| CSV → FB conversion |
✅ |
Phase 7 |
tests/parametrized/test_csv_conversion.py |
| CALL BY REFERENCE |
✅ |
Phase 8 |
tests/parametrized/test_call_search.py |
| CALL BY VALUE |
✅ |
Phase 8 |
tests/parametrized/test_call_search.py |
| CALL BY CONTENT |
✅ |
Phase 8 |
tests/parametrized/test_call_search.py |
| SEARCH ALL (binary) |
✅ |
Phase 8 |
tests/parametrized/test_call_search.py |
| SEARCH ALL (duplicate) |
✅ |
Phase 8 |
tests/parametrized/test_call_search.py |
| SORT (ascending) |
✅ |
Phase 8 |
tests/parametrized/test_sort_merge.py |
| SORT (descending) |
✅ |
Phase 8 |
tests/parametrized/test_sort_merge.py |
| SORT (multiple keys) |
✅ |
Phase 8 |
tests/parametrized/test_sort_merge.py |
| MERGE (2 files) |
✅ |
Phase 8 |
tests/parametrized/test_sort_merge.py |
| MERGE (uneven) |
✅ |
Phase 8 |
tests/parametrized/test_sort_merge.py |
| VL: ODO logic |
✅ |
Phase 9 |
tests/parametrized/test_crosscutting.py |
| LP: PERFORM VARYING |
✅ |
Phase 9 |
tests/parametrized/test_crosscutting.py |
| LP: PERFORM UNTIL |
✅ |
Phase 9 |
tests/parametrized/test_crosscutting.py |
| NP: COMP-3 precision |
✅ |
Phase 9 |
tests/parametrized/test_crosscutting.py |
| NP: ROUNDED clause |
✅ |
Phase 9 |
tests/parametrized/test_crosscutting.py |
| D: Leap year / Month end |
✅ |
Phase 9 |
tests/parametrized/test_crosscutting.py |
| 日文: 全角片假名 |
✅ |
Phase 10 |
tests/parametrized/test_japanese.py |
| 日文: 半角片假名 |
✅ |
Phase 10 |
tests/parametrized/test_japanese.py |
| 日文: SJIS 5C/7C 问题文字 |
✅ |
Phase 10 |
tests/parametrized/test_japanese.py |
| 日文: 和历日期 |
✅ |
Phase 10 |
tests/parametrized/test_japanese.py |
| 日文: Encoding round-trip |
✅ |
Phase 10 |
tests/parametrized/test_japanese.py |
33+2 = 35 程序类型全覆盖
类型别测试矩阵 (Phase 7-10 测试文件清单)
Phase 7: 匹配/分割/CSV 转换 (~8 测试文件)
| 测试文件 |
测试内容 |
测试数 |
tests/parametrized/test_parametrized.py |
8个公开函数的正常路径+边界 |
~50 |
tests/parametrized/test_matching.py |
1:1/1:N/N:1 匹配 + KEY 中断 + gcov |
~20 |
tests/parametrized/test_division.py |
50%/25%/100% 分割 + 余数处理 |
~15 |
tests/parametrized/test_csv_conversion.py |
CSV→FB 字段数/类型/引号 |
~13 |
Phase 8: CALL / SEARCH ALL / SORT / MERGE (~2 测试文件)
| 测试文件 |
测试内容 |
测试数 |
tests/parametrized/test_call_search.py |
CALL 3种传递 + SEARCH ALL 查找 |
~22 |
tests/parametrized/test_sort_merge.py |
SORT 升/降序 + MERGE 均匀/不均 |
~18 |
Phase 9: 横断功能测试 (~1 测试文件, ~20 tests)
| 测试文件 |
领域 |
测试数 |
tests/parametrized/test_crosscutting.py |
VL(ODO)+LP(PERFORM)+NP(COMP3/ROUNDED)+D(闰年/月末/和历) |
~20 |
Phase 10: 日文测试 (~1 测试文件, ~20 tests)
| 测试文件 |
测试内容 |
测试数 |
tests/parametrized/test_japanese.py |
全角/半角/SJIS 5C/7C/和历/编码回环 |
~20 |
横跨功能测试行 (Phase 9)
横断功能测试覆盖 COBOL 运行时四大核心领域:
| 领域 |
缩写 |
测试内容 |
测试数 |
| 可变长 / ODO |
VL |
OCCURS DEPENDING ON 长度/读取/边界 |
5 |
| 循环 / PERFORM |
LP |
PERFORM VARYING 升/降/步进 + UNTIL |
5 |
| 数值精度 |
NP |
COMP-3 BCD 解码 + ROUNDED 上下舍入 |
5 |
| 日期逻辑 |
D |
闰年/月末/和历转换 |
5 |
日文测试行 (Phase 10)
日文测试覆盖 COBOL 日文处理的特殊场景:
| 测试分组 |
内容 |
测试数 |
| 查找表常量 |
全角平/片假名/半角/SJIS 问题文字/和历边界 |
4 |
| 全角文字生成 |
PIC N 字段填充 + 长度 + 内容验证 |
3 |
| 半角片假名生成 |
PIC X 字段填充 + 长度验证 |
2 |
| SJIS 问题文字 |
5C 问题 + 7C 问题文字 |
2 |
| 和历日期 |
标准格式 + 边界切换 + 默认参数 |
3 |
| 编码回环 |
Shift-JIS ↔ UTF-8 回环 + 数据类型选择 |
4 |
| 数据类型选择 |
PIC N/9/X 正确分类 |
2 |
覆盖率目标
测试执行计划
Phase A: 核心模块单元 (~15分)
Phase B: 管道中枢 + Web (~10分)
Phase C: 边界 + 非功能 (~15分)
Phase D: runner + JCL + 其他模块 (~8分)
Phase E: HINA 统合测试 (~2分)
Phase F: 回归测试 (~1分)
Phase G: 実 COBOL 测试 (~5分, WSL + GnuCOBOL)
Phase H: E2E Playwright (~3分, 需启动 server)
Phase I: 类型别测试 Phase 7-10 (~2分)
一键全自动化
预期结果
| 测试维度 |
计划数 |
最低通过 |
通过率目标 |
| L0 单元测试 |
280 |
270 |
≥96% |
| L1 类型测试 (Phase 7-8) |
80 |
75 |
≥93% |
| 横跨功能测试 (Phase 9) |
20 |
18 |
≥90% |
| 日文测试 (Phase 10) |
20 |
18 |
≥90% |
| L2 HINA 统合 |
8 |
6 |
≥75% |
| L3 実 COBOL |
4 |
4 |
100% |
| L4 回归 |
112 |
112 |
100% |
| L5 非功能 |
6 |
5 |
≥83% |
| L6 UI E2E |
7 |
7 |
100% |
| 总计 |
~518 |
~500 |
≥96% |
内訳:
已知限制
- Lark 文法:
SD / ASCENDING KEY 未対応, HINA 2个测试跳过
- Windows 编码:
PYTHONIOENCODING=utf-8 或 python -X utf8 必须, GBK 错误频繁
- Docker 不可用: 当前环境无 Docker Desktop, Spark runner 不可测试
- 外部依赖: 実 COBOL 测试需要 WSL + GnuCOBOL + Java (GnuCOBOL 3.1.2.0, OpenJDK 17)
- LLM API 成本: Agent 测试依赖 LLM 调用, 缓存命中可降低成本
- 沙盒权限: settings.json 需包含
D:/cobol-java/** 读写权限以便子 Agent 并行开发