# 基准真相原则 —— 防止文档同步问题 **目的**:防止因文档/跟踪文件不匹配导致的测试套件完整性问题。 **经验教训**:CCPM 项目发现 CSV 与文档之间的一致性率仅为 3.2%(93 个测试 ID 中只有 3 个正确匹配)。 --- ## 问题 ### 常见的反模式 项目往往拥有多个真相来源: - 测试用例文档(例如 `02-CLI-TEST-CASES.md`) - 执行跟踪 CSV(例如 `TEST-EXECUTION-TRACKING.csv`) - Bug 跟踪电子表格 - 测试自动化代码 **出问题的环节**: 1. 文档更新了 → CSV 未更新 2. CSV 从旧测试列表中自动生成 → 文档独立定稿 3. 基于 CSV 执行测试 → 执行了错误的测试步骤 4. Bug 报告引用 CSV ID → 无法追溯到正确的测试 ### CCPM 的真实案例 **CSV TC-CLI-012**:"安装不存在的技能" - 步骤:运行 `ccpm install this-skill-does-not-exist-12345` - 预期结果:明确的错误信息 **文档 TC-CLI-012**:"安装已安装的技能" - 步骤:运行 `ccpm install cloudflare-troubleshooting`(已安装) - 预期结果:带有 `--force` 提示的警告信息 **结果**:完全不同的测试!QA 工程师可能执行了错误的测试并报告了不正确的结果。 --- ## 基准真相原则 ### 规则一:单一真相来源 **将某一个文件声明为**测试规范的权威来源: ``` ✅ 正确: 基准真相:02-CLI-TEST-CASES.md(详细的测试规范) 辅助文件:TEST-EXECUTION-TRACKING.csv(仅限执行状态) ❌ 错误: CSV 和文档都包含测试步骤(分歧不可避免) ``` ### 规则二:清晰的角色分离 | 文件类型 | 用途 | 包含内容 | 更新时机 | |-----------|---------|----------|--------------| | **测试用例文档** | 规范 | 前置条件、步骤、预期结果、通过/失败标准 | 测试设计变更时 | | **跟踪 CSV** | 执行跟踪 | 状态、结果、Bug ID、执行日期、备注 | 每次测试执行后 | | **Bug 报告** | 失败记录 | 复现步骤、环境、严重等级、解决方案 | 测试失败时 | ### 规则三:明确引用 在指令中始终指明使用哪个文件: **好**: ```markdown 执行测试用例 TC-CLI-042: 1. 从 02-CLI-TEST-CASES.md(第 15-16 页)读取完整的测试规范 2. 严格按文档步骤执行 3. 在 TEST-EXECUTION-TRACKING.csv 的 TC-CLI-042 行中更新结果 ``` **差**: ```markdown 执行测试用例 TC-CLI-042(未引用源文档) ``` --- ## 预防策略 ### 策略一:自动化 ID 校验 **脚本**:`validate_test_ids.py`(在项目中生成) ```python #!/usr/bin/env python3 """校验文档与 CSV 之间的测试 ID""" import csv import re from pathlib import Path def extract_doc_ids(doc_path): """从 Markdown 文档中提取所有 TC-XXX-YYY 格式的 ID""" with open(doc_path, 'r') as f: content = f.read() pattern = r'TC-[A-Z]+-\d{3}' return set(re.findall(pattern, content)) def extract_csv_ids(csv_path): """从 CSV 中提取所有测试用例 ID""" with open(csv_path, 'r') as f: reader = csv.DictReader(f) return set(row['Test Case ID'] for row in reader if row['Test Case ID']) def validate_sync(doc_path, csv_path): """检查文档与 CSV 之间的一致性""" doc_ids = extract_doc_ids(doc_path) csv_ids = extract_csv_ids(csv_path) matching = doc_ids & csv_ids csv_only = csv_ids - doc_ids doc_only = doc_ids - csv_ids consistency_rate = len(matching) / len(csv_ids) * 100 if csv_ids else 0 print(f"\n{'='*60}") print(f"测试 ID 校验报告") print(f"{'='*60}\n") print(f"✅ 匹配的 ID: {len(matching)}") print(f"⚠️ 仅 CSV 存在的 ID: {len(csv_only)}") print(f"⚠️ 仅文档存在的 ID: {len(doc_only)}") print(f"\n📊 一致性率:{consistency_rate:.1f}%\n") if consistency_rate < 100: print(f"❌ 检测到同步问题!\n") if csv_only: print(f"CSV 中存在但文档中不存在的 ID:{sorted(csv_only)[:5]}") if doc_only: print(f"文档中存在但 CSV 中不存在的 ID:{sorted(doc_only)[:5]}") else: print(f"✅ 完美同步!\n") return consistency_rate >= 95 if __name__ == "__main__": import sys if len(sys.argv) < 3: print("用法:python validate_test_ids.py <文档路径> ") sys.exit(1) doc_path = sys.argv[1] csv_path = sys.argv[2] valid = validate_sync(doc_path, csv_path) sys.exit(0 if valid else 1) ``` **用法**: ```bash python scripts/validate_test_ids.py \ tests/docs/02-CLI-TEST-CASES.md \ tests/docs/templates/TEST-EXECUTION-TRACKING.csv # 输出: # ============================================================ # 测试 ID 校验报告 # ============================================================ # # ✅ 匹配的 ID: 3 # ⚠️ 仅 CSV 存在的 ID: 90 # ⚠️ 仅文档存在的 ID: 0 # # 📊 一致性率:3.2% # # ❌ 检测到同步问题! ``` ### 策略二:ID 映射文档 检测到不匹配时,创建桥接文档: **文件**:`tests/docs/TEST-ID-MAPPING.md` **内容**: ```markdown # 测试 ID 映射 —— CSV 与文档 ## 基准真相 **官方来源**:02-CLI-TEST-CASES.md **跟踪文件**:TEST-EXECUTION-TRACKING.csv(仅限执行跟踪) ## ID 映射表 | CSV ID | 文档 ID | 测试名称 | 匹配状态 | |--------|--------|-----------|--------------| | TC-CLI-001 | TC-CLI-001 | 按名称安装技能 | ✅ 匹配 | | TC-CLI-012 | TC-CLI-008 | 安装不存在的技能 | ❌ 不匹配 | ``` ### 策略三:CSV 使用指南 为 QA 工程师创建明确的说明文档: **文件**:`tests/docs/templates/CSV-USAGE-GUIDE.md` **内容**: ```markdown # TEST-EXECUTION-TRACKING.csv 使用指南 ## ✅ 正确用法 1. **始终使用测试用例文档**作为以下内容的权威来源: - 测试步骤 - 预期结果 - 前置条件 2. **此 CSV 仅用于**: - 跟踪执行状态 - 记录结果(通过/失败) - 链接到 Bug 报告 ## ❌ 不要依赖 CSV 获取测试规范 ``` --- ## 恢复工作流 当发现同步问题时: ### 第一步:评估严重程度 ```bash # 运行 ID 校验脚本 python scripts/validate_test_ids.py <文档> # 一致性率: # 100%: ✅ 无需操作 # 90-99%: ⚠️ 需要小幅修复 # 50-89%: 🔴 需要重大同步 # <50%: 🚨 严重 —— 重新生成 CSV ``` ### 第二步:创建桥接文档 ```bash # 如果一致性率 < 100%,创建: 1. TEST-ID-MAPPING.md(映射 CSV → 文档 ID) 2. CSV-USAGE-GUIDE.md(指导 QA 工程师) ``` ### 第三步:通知团队 ```markdown 主题:[紧急] 测试套件同步问题 —— 测试前请先阅读 团队, 我们发现 CSV 与文档之间存在测试 ID 不匹配: - 一致性率:3.2%(93 个测试中仅 3 个匹配) - 影响:基于 CSV 执行的测试可能使用错误的步骤 - 需执行的操作:继续测试前请先阅读 CSV-USAGE-GUIDE.md 基准真相:02-CLI-TEST-CASES.md(始终信任此文件) 仅限跟踪:TEST-EXECUTION-TRACKING.csv 桥接文档:TEST-ID-MAPPING.md(映射 ID) ``` ### 第四步:重新验证已执行的测试 ```markdown 修复前已执行的测试可能需要重新验证: - TC-CLI-001~003:✅ 正确(ID 匹配) - TC-CLI-029:⚠️ 对照文档 TC-CLI-029 进行验证 - TC-CLI-037:⚠️ 对照文档 TC-CLI-037 进行验证 ``` ### 第五步:长期修复 **选项 A**:保持分离(在活跃测试期间推荐) - CSV = 仅限执行跟踪 - 文档 = 测试规范 - 映射文档桥接差距 **选项 B**:从文档重新生成 CSV(测试后) - 风险:执行历史丢失 - 好处:完美同步 - 时间节点:当前测试周期结束后 --- ## 最佳实践 ### ✅ 应做事项 1. **在项目 README 中提前声明基准真相** 2. **分离关注点**:规范 vs. 跟踪 vs. Bug 3. **定期校验 ID**(每周或在重要里程碑前) 4. **在映射文件中记录偏差** 5. **对 QA 团队进行基准真相原则培训** ### ❌ 不应做事项 1. ❌ 在多个文件中重复测试步骤 2. ❌ 未经校验自动生成跟踪文件 3. ❌ 仅凭 CSV 执行测试 4. ❌ 认为"只是跟踪文件"——ID 很重要! 5. ❌ 忽视微小的不匹配(3% 很快会变成 50%) --- ## QA 项目设置清单 使用 `init_qa_project.py` 时,请确保: - [ ] 在 README 中声明了基准真相 - [ ] CSV 仅包含 ID 和跟踪字段(无详细步骤) - [ ] 测试用例文档在 CSV 生成前已完备 - [ ] ID 校验脚本已添加到项目 - [ ] CSV 使用指南已包含在 templates/ 目录下 - [ ] QA 工程师已接受关于应信任哪个文件的培训 --- ## 与 qa-expert 技能的集成 使用 `qa-expert` 初始化项目时: ```bash python scripts/init_qa_project.py my-app ./ # 这将创建: tests/docs/ ├── README.md (声明基准真相) ├── 02-CLI-TEST-CASES.md (权威规范) ├── TEST-ID-MAPPING.md (如果需要) └── templates/ ├── TEST-EXECUTION-TRACKING.csv (仅限跟踪) ├── CSV-USAGE-GUIDE.md (使用说明) └── validate_test_ids.py (校验脚本) ``` --- ## 成功标准 **当满足以下条件时,你的测试套件具有良好的完整性**: - ✅ ID 一致性率 ≥ 95% - ✅ QA 工程师知道应信任哪个文件 - ✅ 跟踪 CSV 仅包含状态(不含步骤) - ✅ 校验脚本每周运行 - ✅ 团队已接受基准真相原则培训 **警示信号**: - 🚩 多个文件包含测试步骤 - 🚩 CSV 中的测试名称与文档不同 - 🚩 QA 工程师"偏爱"CSV 而非文档 - 🚩 无人知道哪个文件是权威来源 - 🚩 测试 ID 随时间推移产生分歧 --- **文档版本**:1.0 **创建日期**:2025-11-10 **基于**:CCPM 测试套件完整性事件(3.2% 一致性率) **优先级**:🔴 P0(对测试套件质量至关重要)