From 0438164b1180043077f182712684c044a84e2eb1 Mon Sep 17 00:00:00 2001 From: zhang_taoming <854317252@qq.com> Date: Sun, 13 Sep 2026 15:05:43 +0800 Subject: [PATCH] feat(runner): merge black-box groups into COBOL vs Java report --- cobol_testgen/runner.py | 79 +++++++++++++++---------- tests/cobol_testgen/test_java_report.py | 40 +++++++++++++ 2 files changed, 88 insertions(+), 31 deletions(-) create mode 100644 tests/cobol_testgen/test_java_report.py diff --git a/cobol_testgen/runner.py b/cobol_testgen/runner.py index d6a3a84..6d4123a 100644 --- a/cobol_testgen/runner.py +++ b/cobol_testgen/runner.py @@ -724,6 +724,36 @@ def _run_java_scene(program_name: str, scene_id: str, java_out_dir, temp_dir: st return {'label': label, 'rc': rc, 'summaries': summaries} +def _append_java_report_body(lines: list, rep: dict) -> None: + """渲染单个组的比对明细(表 + 差异示例)。""" + lines.append('') + if rep.get('error'): + lines.append(f'运行/比对异常: {rep["error"]}') + lines.append('') + return + if not rep['summaries']: + lines.append('(无输出 FD 可比对)') + lines.append('') + return + lines.append('| 出力FD | COBOL记录数 | Java记录数 | 一致 | 不一致 | 判定 |') + lines.append('|--------|------------|-----------|------|--------|------|') + for s in rep['summaries']: + verdict = '一致' if s['mismatched'] == 0 else '不一致' + lines.append( + f"| {s['assign']} | {s['cobol_count']} | {s['java_count']} " + f"| {s['matched']} | {s['mismatched']} | {verdict} |") + diff = [s for s in rep['summaries'] if s['mismatched'] > 0] + if diff: + lines.append('') + lines.append('**差异示例(最多 3 条/FD)**:') + for s in diff: + for smp in s['samples']: + lines.append(f"- {s['assign']}[记录{smp['index']}] 首异位置={smp['pos']}") + lines.append(f" - COBOL: `{smp['cobol']}`") + lines.append(f" - Java : `{smp['java']}`") + lines.append('') + + def _write_java_test_report(outdir: str, program_name: str, results: list, java_reports: list[dict]) -> None: @@ -743,36 +773,22 @@ def _write_java_test_report(outdir: str, program_name: str, lines.append(f"| {r.name} | {r.returncode} | {mark} |") lines.append('') + white = [r for r in java_reports if r.get('section') != 'black_box'] + black = [r for r in java_reports if r.get('section') == 'black_box'] + lines.append('## 2. Java 执行与出力比对(逐组逐 FD)') lines.append('') - for rep in java_reports: - lines.append(f'### 2.{java_reports.index(rep) + 1} 组 `{rep["label"]}` (Java rc={rep.get("rc", "N/A")})') - lines.append('') - if rep.get('error'): - lines.append(f'运行/比对异常: {rep["error"]}') - lines.append('') - continue - if not rep['summaries']: - lines.append('(无输出 FD 可比对)') - lines.append('') - continue - lines.append('| 出力FD | COBOL记录数 | Java记录数 | 一致 | 不一致 | 判定 |') - lines.append('|--------|------------|-----------|------|--------|------|') - for s in rep['summaries']: - verdict = '一致' if s['mismatched'] == 0 else '不一致' - lines.append( - f"| {s['assign']} | {s['cobol_count']} | {s['java_count']} " - f"| {s['matched']} | {s['mismatched']} | {verdict} |") - diff = [s for s in rep['summaries'] if s['mismatched'] > 0] - if diff: - lines.append('') - lines.append('**差异示例(最多 3 条/FD)**:') - for s in diff: - for smp in s['samples']: - lines.append(f"- {s['assign']}[记录{smp['index']}] 首异位置={smp['pos']}") - lines.append(f" - COBOL: `{smp['cobol']}`") - lines.append(f" - Java : `{smp['java']}`") + for idx, rep in enumerate(white): + lines.append(f'### 2.{idx + 1} 组 `{rep["label"]}` (Java rc={rep.get("rc", "N/A")})') + _append_java_report_body(lines, rep) + + if black: + lines.append('## 2b. 黑盒组 Java 执行与出力比对') lines.append('') + for idx, rep in enumerate(black): + lines.append(f'### 2b.{idx + 1} 黑盒组 `{rep["label"]}` ' + f'(Java rc={rep.get("rc", "N/A")})') + _append_java_report_body(lines, rep) all_fd = [s for rep in java_reports for s in rep.get('summaries', [])] total_match = sum(s['matched'] for s in all_fd) @@ -809,8 +825,9 @@ def run_all(program_name: str, outdir: str, temp_dir: str, multi_write_fds: set | None = None, skip_records: list[dict] | None = None, skip_term_types: list[str] | None = None, - java_src_dir: str | None = None - ) -> tuple[list[GroupResult], dict[int, int] | None]: + java_src_dir: str | None = None, + write_report: bool = True + ) -> tuple[list[GroupResult], dict[int, int] | None, list[dict]]: """完整编排:编译 → 准备目录 → 逐组执行 → 出力保存。 Returns: @@ -987,13 +1004,13 @@ def run_all(program_name: str, outdir: str, temp_dir: str, logger.info(f" Merged gcov from {len(gcov_data_sets)} runs ({len(merged_gcov)} lines)") # ── 5. 生成 COBOL vs Java 出力比对测试报告 ── - if java_cfg and java_reports: + if write_report and java_cfg and java_reports: try: _write_java_test_report(outdir, program_name, results, java_reports) except Exception as e: # noqa: BLE001 logger.warning(f" 测试报告生成失败: {e}") - return results, merged_gcov + return results, merged_gcov, java_reports # ── 外部(黑盒)数据组执行 ── diff --git a/tests/cobol_testgen/test_java_report.py b/tests/cobol_testgen/test_java_report.py new file mode 100644 index 0000000..8ecbcb1 --- /dev/null +++ b/tests/cobol_testgen/test_java_report.py @@ -0,0 +1,40 @@ +"""COBOL vs Java 测试报告:白盒向后兼容 + 黑盒节""" + +import os +import sys + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) + +from cobol_testgen.runner import _write_java_test_report, GroupResult + + +def _summary(assign="W01", matched=1, mismatched=0): + return {"assign": assign, "cobol_count": matched + mismatched, + "java_count": matched + mismatched, "matched": matched, + "mismatched": mismatched, "samples": []} + + +def test_report_white_only_has_no_black_section(tmp_path): + results = [GroupResult(name="P_main", returncode=0, passed=True)] + reports = [{"label": "main", "rc": 0, "summaries": [_summary()]}] + _write_java_test_report(str(tmp_path), "P", results, reports) + text = (tmp_path / "P_测试报告.md").read_text(encoding="utf-8") + assert "### 2.1 组 `main`" in text + assert "## 2b." not in text + + +def test_report_with_black_section(tmp_path): + results = [ + GroupResult(name="P_main", returncode=0, passed=True), + GroupResult(name="P_black_box_g1", returncode=0, passed=True), + ] + reports = [ + {"label": "main", "rc": 0, "summaries": [_summary()]}, + {"label": "g1", "section": "black_box", "rc": 0, + "summaries": [_summary(assign="W02", mismatched=1)]}, + ] + _write_java_test_report(str(tmp_path), "P", results, reports) + text = (tmp_path / "P_测试报告.md").read_text(encoding="utf-8") + assert "### 2.1 组 `main`" in text + assert "## 2b. 黑盒组 Java 执行与出力比对" in text + assert "### 2b.1 黑盒组 `g1`" in text