From 076fb25eda5de618cd2b2725fe93bbd2a9dc7b97 Mon Sep 17 00:00:00 2001 From: Peter Zhang <18501667167@qq.com> Date: Tue, 2 Jun 2026 14:20:38 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=5Fmeasure=5Fcoverage=20overall=20?= =?UTF-8?q?=E6=8E=92=E9=99=A4=E9=9B=B6=E5=86=85=E5=AE=B9=E7=BB=B4=E5=BA=A6?= =?UTF-8?q?=20-=20Closes=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 3 个回归测试验证 total=0 的维度不参与 overall 计算: - 零内容维度被正确排除 - 所有维度有内容则全部参与 - 无内容时返回 0.0 fix 已在 1a867b0 合入,本次补充 UT 覆盖。 Co-Authored-By: Claude Opus 4.7 --- tests/acceptance/test_main_health.py | 79 ++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/tests/acceptance/test_main_health.py b/tests/acceptance/test_main_health.py index 0b8d28f..41a5551 100644 --- a/tests/acceptance/test_main_health.py +++ b/tests/acceptance/test_main_health.py @@ -291,6 +291,85 @@ def _measure_coverage(ir_data: dict, parsed_data: dict) -> dict: } +def test_measure_coverage_excludes_zero_dimensions(): + """#36: dimensions with total=0 must not drag down the overall rate. + + When diagram total=0, the overall should be computed from sections and tables + only, not include a 0% diagram entry that makes the goal unreachable. + """ + parsed_data = { + "sections": [ + {"source": "3.1.1 功能A", "blocks": [ + {"type": "table", "rows": [{"cell": "1"}, {"cell": "2"}]} + ]} + ], + "image_analysis": [], # no diagrams → total=0 + } + # IR that covers the section but no table rows (table coverage = 0/2) + ir_data = { + "rules": [ + {"sources": [{"section": "3.1.1"}]} # 1 section covered, 0 tables + ] + } + + cov = _measure_coverage(ir_data, parsed_data) + + # Section: 1/1 = 100%, Table: 0/2 = 0%, Diagram: total=0 → excluded + assert cov["section_coverage"]["total"] == 1 + assert cov["section_coverage"]["rate"] == 1.0 + assert cov["table_coverage"]["total_rows"] == 2 + assert cov["table_coverage"]["rate"] == 0.0 + assert cov["diagram_coverage"]["total"] == 0 + assert cov["diagram_coverage"]["rate"] == 1.0 # _safe_rate: 0/0 → 1.0 + + # Key assertion: diagram (total=0) is excluded from overall + # overall = (1.0 + 0.0) / 2 = 0.5 + # NOT (1.0 + 0.0 + 1.0) / 3 = 0.667 + assert cov["overall_rate"] == 0.5, ( + f"Expected overall 0.5 (sections + tables only), got {cov['overall_rate']}. " + f"Zero-content dimension may be leaking into the average." + ) + + +def test_measure_coverage_all_dimensions_have_content(): + """When all dimensions have content, all should be included.""" + parsed_data = { + "sections": [ + {"source": "3.1.1 功能A", "blocks": [ + {"type": "table", "rows": [{"cell": "1"}]} + ]} + ], + "image_analysis": [{"type": "flowchart", "rid": "img_001"}], + } + ir_data = { + "rules": [ + {"sources": [{"section": "3.1.1"}]}, + {"sources": [{"type": "table", "section": "3.1.1", "row": 0}]}, + {"sources": [{"type": "logic_tree", "image_id": "img_001"}]}, + ] + } + + cov = _measure_coverage(ir_data, parsed_data) + + # All three dimensions have content → all included + assert cov["section_coverage"]["total"] == 1 + assert cov["table_coverage"]["total_rows"] == 1 + assert cov["diagram_coverage"]["total"] == 1 + # overall = (1.0 + 1.0 + 1.0) / 3 = 1.0 + assert cov["overall_rate"] == 1.0, ( + f"Expected overall 1.0 (all covered), got {cov['overall_rate']}" + ) + + +def test_measure_coverage_no_content_returns_zero(): + """When no dimensions have content, overall should be 0.0.""" + parsed_data = {"sections": [], "image_analysis": []} + ir_data = {"rules": []} + + cov = _measure_coverage(ir_data, parsed_data) + assert cov["overall_rate"] == 0.0 + + def test_layer_b_coverage( ir_data: dict, parsed_data: dict | None, -- 2.52.0