Loading...
Loading...
Compare original and translation side by side
| You want to... | Go to |
|---|---|
| Find which lines/branches each test uniquely covers | Coverage Fingerprinting |
| Decide if "same coverage" means "delete one" | The Coverage-Equality Trap |
| Surface copy-pasted near-duplicate tests | Near-Duplicate Clustering |
| Find never-failing and always-flaky tests | Mining CI History |
| Decide redundant vs obsolete vs low-value vs keep | Prune Decision Rules |
| Split a flat suite into smoke/core/extended | Tiering |
| Safely delete the tests you flagged | Destructive Safety |
| Produce the "what we deleted and why" record | The Audit Record |
.agents/qa-project-context.mdrisk-based-testing.agents/qa-project-context.mdrisk-based-testing--covpytest --cov=src --cov-branch --cov-context=test--cov-context=testswitch_context()--cov-branchifelse.coveragecontextline_bitsarc.coverage(file, line)(file, branch-arc)references/coverage-fingerprinting.md.coverage--coveragecoverage-final.json--covpytest --cov=src --cov-branch --cov-context=test--cov-context=testswitch_context()--cov-branchifelse.coveragecontextline_bitsarc(文件, 行号)(文件, 分支弧)references/coverage-fingerprinting.md.coverage--coveragecoverage-final.jsonCoverage equality does not prove the tests have the same assertions, the same inputs, or the same oracle. Two tests can cover identical lines while one asserts the HTTP status and the other asserts the response body, or while they pass different edge-case inputs. One covers same lines but asserts different values; the other covers same lines but checks different state. Coverage measures execution, not verification.
references/mutation-confirmation.md覆盖率相等并不证明测试具有相同的断言、相同的输入或相同的验证逻辑。 两个测试可覆盖相同代码行,其中一个断言HTTP状态码,另一个断言响应体;或者它们传入不同的边缘场景输入。一个测试覆盖相同代码行但断言不同值;另一个覆盖相同代码行但检查不同状态。覆盖率衡量的是执行情况,而非验证情况。
references/mutation-confirmation.mddiffreferences/clustering.mddiffreferences/clustering.mdtest-reliabilityreferences/ci-history-mining.mdtest-reliabilityreferences/ci-history-mining.md| Category | Definition (the test is...) | Disposition |
|---|---|---|
| Redundant | subsumed by another test — covers the same lines AND the survivor kills the same mutants (§2) | merge or delete — but only after the mutation-kill check confirms subsumption; quarantine first |
| Obsolete | testing a feature that was removed / dead code / a path that no longer exists | delete — the code it tested is gone; verify the target truly no longer exists, then remove |
| Low-value | never failed AND trivial (a getter, a no-op, no meaningful assertion) | quarantine / route to review — low value is not zero value; confirm before removal |
| Keep | covers something uniquely, catches defects (positive defect-detection history), or guards a high-risk path | keep — protected regardless of coverage overlap |
redundant => merge/delete-after-mutation-checkobsolete => deletelow-value => quarantine/reviewkeep => keeprm| 类别 | 定义(测试...) | 处置方式 |
|---|---|---|
| 冗余 | 被另一个测试包含——覆盖相同代码行,且保留的测试能杀死相同的突变体(第2节) | 合并或删除——但仅在突变测试确认包含关系后;先隔离 |
| 过时 | 测试已移除的功能/死代码/不再存在的路径 | 删除——被测代码已不存在;确认目标确实不再存在后再移除 |
| 低价值 | 从未失败且无实际意义(仅测试 getter、空操作、无有效断言) | 隔离/提交审核——低价值并非零价值;移除前需确认 |
| 保留 | 唯一覆盖某些内容、捕获过缺陷(有缺陷检测历史),或守护高风险路径 | 保留——无论覆盖率是否重叠,均需保护 |
冗余 => 合并/突变测试确认后删除过时 => 删除低价值 => 隔离/审核保留 => 保留risk-based-testing| Tier | Goal | Selection evidence |
|---|---|---|
| Smoke | fast, runs on every push, a few minutes, critical paths only | highest-risk paths + proven defect-catchers; fast enough to gate every commit |
| Core | per-PR / merge gate | all critical + high-risk coverage, broader than smoke |
| Extended | full / nightly / slow / pre-release | everything else — exhaustive, long-running, edge cases |
@pytest.mark.smoke@pytest.mark.extendedpytest -m smokereferences/tiering.mdrisk-based-testing| 层级 | 目标 | 选择依据 |
|---|---|---|
| 冒烟 | 快速,每次推送都运行,耗时数分钟,仅覆盖关键路径 | 最高风险路径 + 已证明的缺陷捕获能力;速度足够快,可作为每次提交的门禁 |
| 核心 | 作为PR/合并门禁 | 所有关键+高风险覆盖范围,比冒烟测试更全面 |
| 扩展 | 完整/夜间/慢速/预发布运行 | 所有其他测试—— exhaustive、运行时间长、覆盖边缘场景 |
@pytest.mark.smoke@pytest.mark.extendedpytest -m smokereferences/tiering.mdrmrm@pytest.mark.skip(reason="curation-2026-Q2, see audit row")xfail.skipquarantine/deprecated/references/destructive-safety.md@pytest.mark.skip(reason="curation-2026-Q2, see audit row")xfail.skipquarantine/deprecated/references/destructive-safety.mddocs/test-curation-log.mdreferences/audit-record.mddocs/test-curation-log.mdreferences/audit-record.md--cov=src--cov-context=test.coverage--cov=src--cov-context=test.coveragermsqlite3 .coverage "SELECT COUNT(*) FROM context WHERE context != '';"--cov-context=testredundantmutation_checkyesgrep -c 'redundant' docs/test-curation-log.mdmutation_checkgit log --diff-filter=D --name-only -- tests/ | grep test_tests/quarantine/pytest --collect-only -m skippytest -m smoke --collect-onlypytest -m "smoke or core or extended" --collect-onlyredundantsuperseded_bycoverage_deltamutation_checkcoverage_delta0 lines / 0 branchessqlite3 .coverage "SELECT COUNT(*) FROM context WHERE context != '';"--cov-context=test冗余mutation_checkyesgrep -c 'redundant' docs/test-curation-log.mdmutation_checkgit log --diff-filter=D --name-only -- tests/ | grep test_tests/quarantine/pytest --collect-only -m skippytest -m smoke --collect-onlypytest -m "smoke or core or extended" --collect-only冗余superseded_bycoverage_deltamutation_checkcoverage_delta0 lines / 0 branches--cov-context=test--cov-branchpytest -m smoke--cov-context=test--cov-branchpytest -m smokereferences/references/.coverage.coverage