test(物流公司管理需求): 需求文档与 QE Fleet 全流程设计产物入库
- 需求 v1.1 + 2026-09-29 需求方确认的 Q7~Q19 决议(含 BR-07/BR-09/6.7/6.9 矛盾表述修订) - 测试点 159 个、测试用例 164 条(P0 55/P1 81/P2 23/P3 5),需求→测试点→用例三级追溯覆盖率 100% - 质量裁决 PASS(首轮 PASS_WITH_FIX,13 项待确认确认后复裁决升级);评审原始 2 阻断项+9 建议项+3 优化项已全部修复 - 确认单:与 4 个历史需求均为并行关系、0 冲突、0 回写 - 附导出 v1/v2 版本快照、Playwright/Appium 脚本骨架、覆盖率审计脚本与指标、评审修复脚本
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""按《评审报告》修复用例文件:2 个阻断项 + 9 条建议项 + 1 处笔误。
|
||||
|
||||
每条替换均断言命中次数,任一不命中即抛错并中止,保证不误伤其它行。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
REPO = Path(__file__).resolve().parent.parent
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
CASES = REPO / "output" / "test_cases" / "物流公司管理需求_测试用例.md"
|
||||
|
||||
# ---------- GB 32100 校验位 ----------
|
||||
CHARSET = "0123456789ABCDEFGHJKLMNPQRTUWXY"
|
||||
WEIGHTS = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28]
|
||||
|
||||
|
||||
def uscc_check_char(body17: str) -> str:
|
||||
assert len(body17) == 17, body17
|
||||
total = sum(CHARSET.index(ch) * WEIGHTS[i] for i, ch in enumerate(body17))
|
||||
rem = 31 - (total % 31)
|
||||
return CHARSET[0 if rem == 31 else rem]
|
||||
|
||||
|
||||
def verify_uscc(uscc: str) -> bool:
|
||||
return len(uscc) == 18 and uscc_check_char(uscc[:17]) == uscc[17]
|
||||
|
||||
|
||||
# 自检:对已知有效样本验证算法
|
||||
assert verify_uscc("91530102MA6N4K7X52"), "算法自检失败(1)"
|
||||
assert verify_uscc("91530103MA6P8Q2D7F"), "算法自检失败(2)"
|
||||
NEW_BODY = "91530102MA6BA5C31"
|
||||
NEW_USCC = NEW_BODY + uscc_check_char(NEW_BODY)
|
||||
assert verify_uscc(NEW_USCC), "新样本自检失败"
|
||||
print(f"061 重建样本新信用代码: {NEW_USCC}")
|
||||
|
||||
# ---------- 修复项:(用例编号, 列定位说明, 旧文本, 新文本) ----------
|
||||
FIXES: list[tuple[str, str, str, str]] = [
|
||||
# B-001
|
||||
("PLT_BSC_LC_028", "预期结果",
|
||||
"3. 纯空格提交按未填处理被阻断(trim 后为空口径)",
|
||||
"3. 纯空格提交的实际行为记录(按空拦截 或 通过),与测试数据 §10 补充-6 口径比对后回归(评审确认前不得静默按单一口径判定)"),
|
||||
("PLT_BSC_LC_028", "备注",
|
||||
"对应TP-B-010;REQ-007 |",
|
||||
"对应TP-B-010;REQ-007;[待确认] 纯空格/空白字符在必填字段中是否按空处理(见测试数据 §10 补充-6,与 PLT_BSC_LC_022 同口径) |"),
|
||||
("PLT_BSC_LC_032", "预期结果",
|
||||
"3. 纯空格按未填处理被阻断",
|
||||
"3. 纯空格提交的实际行为记录(按空拦截 或 通过),与 PLT_BSC_LC_022 口径比对后回归"),
|
||||
("PLT_BSC_LC_032", "备注",
|
||||
"对应TP-B-014;REQ-007(漏测清单 §1 超长字符) |",
|
||||
"对应TP-B-014;REQ-007(漏测清单 §1 超长字符);[待确认] 纯空格/空白字符是否按空处理(见测试数据 §10 补充-6) |"),
|
||||
# B-002
|
||||
("PLT_BSC_LC_073", "测试步骤",
|
||||
"4. 核对上传后文件名展示",
|
||||
"4. 核对上传后文件名展示<br>5. 上传大写扩展名样本(合同.PDF、合同.Jpg,AT-03)并记录实际口径"),
|
||||
("PLT_BSC_LC_073", "预期结果",
|
||||
"4. 无扩展名文件(\"合同附件\")被拒绝;拒绝后不产生上传残留",
|
||||
"4. 无扩展名文件(\"合同附件\")被拒绝;拒绝后不产生上传残留<br>5. 大写扩展名的实际处理行为记录(大小写不敏感放行 或 仅接受小写并提示),与评审结论对齐后回归,不得静默按单一口径断言"),
|
||||
("PLT_BSC_LC_073", "备注",
|
||||
"对应TP-E-012;REQ-019/BR-03 |",
|
||||
"对应TP-E-012;REQ-019/BR-03;[待确认] 合同附件扩展名大小写口径(.PDF/.Jpg 是否放行,见测试数据 §10 补充-1) |"),
|
||||
("PLT_BSC_LC_074", "备注",
|
||||
"对应TP-E-013;REQ-019(漏测清单 §1;0 字节为观察项) |",
|
||||
"对应TP-E-013;REQ-019(漏测清单 §1;0 字节为观察项);[待确认] 合同附件扩展名大小写口径(.PDF/.Jpg 是否放行,见测试数据 §10 补充-1) |"),
|
||||
# S-001
|
||||
("PLT_BSC_LC_017", "测试步骤",
|
||||
"3. 上传营业执照_测试甲.jpg 后再次提交<br>4. 删除已上传的营业执照后再次提交",
|
||||
"3. 上传营业执照_测试甲.jpg 后再次提交(验证提交不再因营业执照被阻断;完整成功链路由 PLT_BSC_LC_038 覆盖)<br>4. 在新增页重新打开表单(名称改用\"云南测试营业执照校验物流有限公司2\"等新唯一值),上传营业执照后删除该证件,再次提交"),
|
||||
("PLT_BSC_LC_017", "预期结果",
|
||||
"3. 上传后提交不再因营业执照阻断并保存成功<br>4. 删除已上传营业执照后提交再次被阻断(删除动作同步清空暂存值)",
|
||||
"3. 提交不再因营业执照被阻断(阻断原因不再指向营业执照;表单可按 038 用例完成保存)<br>4. 删除已上传营业执照后提交再次被阻断(删除动作同步清空暂存值)"),
|
||||
# S-002
|
||||
("PLT_BSC_LC_049", "测试步骤",
|
||||
"4. 再次点击删除并在确认框中确认",
|
||||
"4. 再次点击删除并在确认框中确认,记录删除结果(本步完成后 LC-04 即为已逻辑删除状态)"),
|
||||
("PLT_BSC_LC_054", "备注",
|
||||
"对应TP-D-006;REQ-013/验收要点 2/6.5 |",
|
||||
"对应TP-D-006;REQ-013/验收要点 2/6.5;前置承接:LC-04 确认删除由本用例唯一执行(PLT_BSC_LC_049 步骤 4 仅记录结果);若 049 已执行确认删除,本用例前置改为\"LC-04 已逻辑删除\"、步骤 1 改用新造可删除公司 |"),
|
||||
# S-003 + S-004
|
||||
("PLT_BSC_LC_061", "测试步骤",
|
||||
"1. 用\"玉溪测试丁货运代理有限公司\"+ 91530402MA6U2W5J8J 新建公司提交<br>2. 用简称码 YND 新建另一公司提交<br>3. 核对新建成功与列表展示<br>4. 核对导出与统计是否将新旧两家视为同一",
|
||||
"1. 新造临时公司(\"云南测试重建样本物流有限公司\"+" + NEW_USCC + ",简称码 DL6)并删除该临时公司<br>2. 用与临时公司完全相同的三元组(名称+" + NEW_USCC + "+简称码 DL6)新建公司提交<br>3. 核对新建成功与列表展示<br>4. 核对导出与统计是否将新旧两家视为同一"),
|
||||
("PLT_BSC_LC_061", "预期结果",
|
||||
"2. 新建公司与已删除行在数据库并存(deleted=0 与 deleted=1 两条记录),无唯一性误拦<br>3. 列表仅展示新建公司(1 条),导出/统计不混淆新旧",
|
||||
"2. 新建公司与已删除行在数据库并存(deleted=0 与 deleted=1 各 1 条,共 2 条记录),无唯一性误拦<br>3. 列表仅展示新建公司(1 条,不含已删除行),导出/统计不混淆新旧"),
|
||||
("PLT_BSC_LC_061", "备注",
|
||||
"对应TP-D-013;BR-01+BR-04 组合/REQ-009 |",
|
||||
"对应TP-D-013;BR-01+BR-04 组合/REQ-009;本用例为\"已删除后三元组复用\"的唯一创建执行点(PLT_BSC_LC_034/035/036 不得再创建同名/同码/同简称码公司,顺序执行时以本用例的重建记录为准) |"),
|
||||
("PLT_BSC_LC_034", "备注",
|
||||
"对应TP-B-015;REQ-009/BR-01 |",
|
||||
"对应TP-B-015;REQ-009/BR-01;执行顺序:本用例创建的重建记录与 PLT_BSC_LC_061 互斥,二者只执行其一(推荐以 061 为唯一重建执行点,本用例改为核对 061 已创建记录) |"),
|
||||
("PLT_BSC_LC_035", "备注",
|
||||
"对应TP-B-016;REQ-009/BR-01(跨机构同码场景见 PLT_TMS_LC_057/061) |",
|
||||
"对应TP-B-016;REQ-009/BR-01(跨机构同码场景见 PLT_TMS_LC_057/061);执行顺序:本用例的同码重建与 PLT_BSC_LC_061 互斥,二者只执行其一(推荐以 061 为唯一重建执行点) |"),
|
||||
("PLT_BSC_LC_036", "备注",
|
||||
"对应TP-B-017;BR-01/REQ-009;[待确认] 简称码空值是否参与全平台唯一、DB 唯一约束对 NULL/空串的处理语义(口径③,见分析 11.2 #4) |",
|
||||
"对应TP-B-017;BR-01/REQ-009;[待确认] 简称码空值是否参与全平台唯一、DB 唯一约束对 NULL/空串的处理语义(口径③,见分析 11.2 #4);执行顺序:本用例的简称码重建与 PLT_BSC_LC_061 互斥,二者只执行其一(推荐以 061 为唯一重建执行点) |"),
|
||||
# S-005
|
||||
("PLT_BSC_LC_052", "测试步骤",
|
||||
"1. 构造\"仅有待生效合同\"公司(用 LC-02 移除引用后重试或新造公司)发起删除<br>2. 构造\"仅有已过期合同\"公司发起删除",
|
||||
"1. 新造公司 A(仅挂待生效合同、无运单/货源引用)发起删除<br>2. 新造公司 B(仅挂已过期合同、无运单/货源引用)发起删除"),
|
||||
("PLT_BSC_LC_052", "预期结果",
|
||||
"1. 仅有待生效合同时删除不因合同条件阻断(提示原因不含生效合同)<br>2. 仅有已过期合同时同样不因合同条件阻断",
|
||||
"1. 公司 A 删除成功(deleted=1、列表消失),提示原因不含\"生效合同\";若产品口径为阻断则按双分支记录实际行为<br>2. 公司 B 删除成功(deleted=1、列表消失),提示原因不含\"生效合同\";若产品口径为阻断则按双分支记录实际行为"),
|
||||
# S-006
|
||||
("PLT_BSC_LC_067", "测试步骤",
|
||||
"4. 在 LC-03 下新增另一条编号 HT-2026-0001 复核允许性",
|
||||
"4. 在 LC-03 下再次新增编号 HT-2026-0001,验证同公司唯一性仍然生效"),
|
||||
# S-007
|
||||
("PLT_TMS_LC_037", "预期结果",
|
||||
"已删除公司是否出现在下拉按快照追溯口径记录实际行为",
|
||||
"已删除公司不出现在打款筛选下拉(与 PLT_BSC_LC_056/TP-D-008/SS-08 一致)"),
|
||||
# S-008
|
||||
("PLT_BSC_LC_069", "测试步骤",
|
||||
"4. 核对每次弹窗状态与提示",
|
||||
"4. 核对每次弹窗状态与提示<br>5. 分别留空签订时间、生效时间、过期时间各保存一次"),
|
||||
("PLT_BSC_LC_069", "预期结果",
|
||||
"4. 所有阻断场景弹窗不关闭、已填内容保留;数据库无非法记录落库",
|
||||
"4. 所有阻断场景弹窗不关闭、已填内容保留;数据库无非法记录落库<br>5. 三项时间任一为空保存均被阻断、错误字段就近标红,弹窗不关闭、数据库无非法记录(样本 CD-04)"),
|
||||
("PLT_BSC_LC_069", "备注",
|
||||
"对应TP-E-008;BR-03/验收要点 4 |",
|
||||
"对应TP-E-008;BR-03/验收要点 4;CD-04 |"),
|
||||
# S-009
|
||||
("PLT_BSC_LC_020", "测试步骤",
|
||||
"1. 营业执照依次上传 .jpg/.jpeg/.png/.pdf 四个文件<br>2. 营业执照上传 .gif/.docx/.txt/无扩展名/.bmp 文件",
|
||||
"1. 营业执照与道路运输经营许可证分别依次上传 .jpg/.jpeg/.png/.pdf 四个文件<br>2. 营业执照与道路运输经营许可证分别上传 .gif/.docx/.txt/无扩展名/.bmp 文件"),
|
||||
("PLT_BSC_LC_020", "预期结果",
|
||||
"1. 营业执照 jpg/jpeg/png/pdf 四格式逐一上传成功并可预览<br>2. 营业执照对 gif/docx/txt/无扩展名/bmp 拒绝并提示格式白名单(注意 bmp 不在证件白名单)",
|
||||
"1. 营业执照与许可证 jpg/jpeg/png/pdf 四格式逐一上传成功并可预览<br>2. 营业执照与许可证对 gif/docx/txt/无扩展名/bmp 拒绝并提示格式白名单(注意 bmp 不在证件白名单)"),
|
||||
("PLT_BSC_LC_020", "备注",
|
||||
"对应TP-B-005;REQ-006(与合同附件白名单差异见 DOC-02 说明) |",
|
||||
"对应TP-B-005;REQ-006(与合同附件白名单差异见 DOC-02 说明);DOC-07 许可证四格式样本 |"),
|
||||
# O-001
|
||||
("PLT_BSC_LC_010", "备注",
|
||||
"(漏收清单 §4 分页)",
|
||||
"(漏测清单 §4 分页)"),
|
||||
]
|
||||
|
||||
# ---------- 执行 ----------
|
||||
lines = CASES.read_text(encoding="utf-8").splitlines(keepends=True)
|
||||
by_case: dict[str, int] = {}
|
||||
for i, line in enumerate(lines):
|
||||
if line.startswith("| PLT_"):
|
||||
by_case[line.split("|")[1].strip()] = i
|
||||
|
||||
applied = 0
|
||||
for case_id, col, old, new in FIXES:
|
||||
li = by_case[case_id]
|
||||
line = lines[li]
|
||||
cnt = line.count(old)
|
||||
if cnt != 1:
|
||||
raise SystemExit(f"❌ {case_id} [{col}] 命中 {cnt} 次(期望 1):{old[:60]!r}")
|
||||
if new in line:
|
||||
raise SystemExit(f"❌ {case_id} [{col}] 目标文本已存在,跳过以免重复:{new[:60]!r}")
|
||||
lines[li] = line.replace(old, new)
|
||||
applied += 1
|
||||
print(f"✅ {case_id} [{col}] 已修复")
|
||||
|
||||
CASES.write_text("".join(lines), encoding="utf-8")
|
||||
print(f"\n共应用 {applied} 处修复 -> {CASES}")
|
||||
Reference in New Issue
Block a user