执行 Admin 测试 SQL
执行 SQL 1。结果区必须看到 template_ready=OK,且 TESTADM-A 到 D 的 generation_ready 都是 OK。
QA field manual · 2026-08-08
给第一次接触该需求的测试人员。目标不是只在后台看到一个箱型字段,而是把“配置、生成、打包校验、晚场重算”四条链路完整走通。
commit 0019b5646c3a98e7c813e0cd14a4ba7561ebf89f01 / REQUIREMENT
一件花材订单先按箱型容量生成推荐方案;仓库真正设箱时再比较实际箱与推荐箱;城市仓晚场有新单时,还要把未出库包裹按新总量重新规划。
flowerWeight,单位 kg,0 表示不参与普通推荐。6001,确认后带 forceFlag=1 重调并留痕。普通箱维护可装花材重量;专用箱容量为 0。
最大箱先装整箱,余数匹配第一个能装下的最小箱。
实际箱与推荐箱比较,生成合规、不符或不可比较状态。
仅城市仓 type=2;已出库不动,其余重排并按需追加。
以当前代码为唯一验收口径。
旧文档有两处已过时:PDA 现在遇到不符不会返回 6001;白天已有蝴蝶兰且晚场再次新增蝴蝶兰时,当前实现会再追加一张蝴蝶兰箱面单。
02 / RULES
下面是执行测试时最容易混淆的口径。建议先用两分钟看完,再开始造数据。
| 规则 | 输入 | 正确结果 |
|---|---|---|
| 普通箱拆分 | 80kg,最大容量 87kg | 1 张 110*60*60 |
| 整箱加余数 | 180kg | 87 + 87 + 6.1,共 3 张 |
| 特殊花材 | 普通45kg + 蝴蝶兰2kg + 蓝色妖姬1kg | 1 张普通箱 + 蝴蝶兰箱 + 蓝妖箱 |
| 中通 | 100kg | ceil(100/45)=3 张,推荐字段为空 |
| 无有效容量 | 所有普通箱 flowerWeight=0 | 回退每 60kg 一件,推荐字段为空 |
| 匹配状态 | 未设箱,或无推荐 | boxMatchStatus=0,尚不可判定合规 |
| 匹配状态 | 实际箱 = 推荐箱 | boxMatchStatus=1 |
| 匹配状态 | 实际箱 ≠ 推荐箱 | boxMatchStatus=2 |
| 晚场状态 0/10 | 未出库 | 一起按新推荐序列覆盖,实际箱不跟随修改 |
| 晚场状态 ≥20 | 已出库 | 任何字段都不改,优先按实际箱容量扣减已带走重量 |
18:05 是当前边界:白场只取 create_time < 18:05,晚场新增判断只认 create_time > 18:05。主流程请用 17:00 和 21:00,避免恰好 18:05 的边界空档。
03 / PREPARE
先填测试日期和接口地址,下面的 cURL 会自动更新。令牌只保存在当前输入框中,刷新页面即清空。
| 检查项 | 要求 | 不满足时 |
|---|---|---|
| 数据库字段 | flower_weight、suggest_pack_id、suggest_pack_info 已存在 | 停止,先补发布 DDL |
| Admin 服务 | 包含本提交,测试接口可调用 | 确认部署分支和实例版本 |
| Supplier 服务 | 包含本提交,账号有打包货区权限 | 更换账号或调整 SQL 货位 |
| 物流配置 | 供应商脚本的 @express_id 是有效物流且不等于 146 | 改成测试环境真实 id |
| 配置缓存 | 直接 SQL 改箱型后等待约 100 秒,或后台保存任一配置刷新 | 旧缓存会让结果看似错误 |
SELECT table_name, column_name, column_type
FROM information_schema.columns
WHERE table_schema = DATABASE()
AND ((table_name = 'xm_bulky_pack_config' AND column_name = 'flower_weight')
OR (table_name = 'xm_bulky_wms_express_package'
AND column_name IN ('suggest_pack_id', 'suggest_pack_info')))
ORDER BY table_name, ordinal_position;
-- 预期恰好返回 3 行
只在测试库执行。Admin 脚本会把 DDL 默认残留的 flower_weight=1.00 清零,并按测试名称清理旧数据。先确认当前连接库名,再执行。
04 / DAY RUN
这组用例证明容量拆分、特殊花材、中通和幂等。TESTADM 数据是 ware_id=0 的 type=1 数据,不能拿去测晚场城市仓重算。
执行 SQL 1。结果区必须看到 template_ready=OK,且 TESTADM-A 到 D 的 generation_ready 都是 OK。
调用一次测试接口。若 SQL 刚修改箱型容量,先等待缓存过期或在后台保存任一箱型。
列表请求不要传 serialNum:1,否则只能看到每组第 1 张,容易误判“没有追加面单”。
A:1 张 110*60*60。B:110*60*60、110*60*60、小件90*20。C:普通 110*45*45,加蝴蝶兰箱与蓝妖箱各 1 张。D:中通 3 张,推荐 id 全为 0。
先记录 TESTADM 包裹总行数和 id,再调用同一个白场接口一次。行数与 id 必须不变。
SELECT p.send_no, p.serial_num, p.package_num,
p.suggest_pack_id, p.suggest_pack_info,
c.flower_weight AS suggest_capacity,
p.total_weight, p.express_status
FROM xm_bulky_wms_express_package p
LEFT JOIN xm_bulky_pack_config c ON c.id = p.suggest_pack_id
WHERE p.send_no LIKE 'TESTADM%'
AND p.data_status = 0
ORDER BY p.send_no, p.serial_num;
-- 幂等前后记录两次结果,COUNT 与 id 集合都应一致
SELECT COUNT(*) AS row_count,
GROUP_CONCAT(id ORDER BY id) AS id_list
FROM xm_bulky_wms_express_package
WHERE send_no LIKE 'TESTADM%' AND data_status = 0;
05 / PACKING
每次测试会修改包裹状态。建议一个动作验证完就重跑 SQL 2 复位,避免前一个用例影响下一个用例。
执行 SQL 前先改 @shelf_a 到 @shelf_d,确保货位在测试打包员权限范围内;把 @express_id 改成有效物流 id,且不要用 146。成功打包后,同一 userId 测下一包需间隔 10 秒。
记录脚本最后输出的包裹 id,扫码内容就是该 id。T-991 待打包;T-992 合规;T-993 含不符;T-994 无推荐。
status=0 时验证 T-991。status=1 时应有 T-992/T-993/T-994;T-993 的 boxMismatchFlag=1。筛选 2 仅 T-993;筛选 1 返回 T-992 和 T-994。
T-991 三行均为 0,但前两行仍有推荐字段;T-992 两行均为 1;T-993 序号1为2、序号2为1;T-994为0。
重置 SQL 后,对 T-991 序号1传推荐箱,forceFlag=0。预期成功,状态10,匹配状态1,不产生强制不符留痕。
重置 SQL 后,对 T-991 序号2选另一个箱。首次 forceFlag=0 必须返回6001且不改状态;立刻用完全相同参数重调,只改 forceFlag=1,应成功并记录一次修改留痕。
T-991 序号3可用任意合法箱直接成功。PDA /pack/finish/scan 用非推荐箱也应直接成功,不返回6001,但要写“扫码枪打包”不符留痕。PDA 账号必须有物流专员角色。
// 货架列表。status=0 查待打包;status=1 查已打包
POST /package/shelf/page
{
"date": "<测试日期>",
"userId": <测试账号ID>,
"userName": "<测试账号名称>",
"status": 1,
"boxMatchFilter": 2,
"current": 1,
"size": 20
}
// 首次设箱。codeContent 填 SQL 输出的包裹 id
POST /package/pack/finish
{
"codeContent": "<包裹ID>",
"userId": <测试账号ID>,
"userName": "<测试账号名称>",
"phone": "13800000000",
"packId": <实际箱ID>,
"packName": "<实际箱名称>",
"url": "",
"shelfPackage": 0,
"forceFlag": 0
}
// 收到 code=6001 后,只把 forceFlag 改成 1,其余参数原样重调
SELECT package_id, origin_pack_id, origin_pack_name,
target_pack_id, target_pack_name,
operate_user_id, operate_user_name, remark, create_time
FROM xm_bulky_package_box_modify_record
WHERE send_no LIKE 'TESTBOX%'
AND data_status = 0
ORDER BY id DESC;
-- 小程序强制使用预期 remark:
-- 实际箱型与推荐箱型不一致,已确认强制使用
-- PDA 不符预期 remark:
-- 扫码枪打包,实际箱型与推荐箱型不一致
06 / NIGHT REPLAN
晚场重算只发生在 type=2 非自营城市仓聚合组。TESTADM-A 到 D 都是 type=1,继续用它们触发晚场接口只会得到“没有重算”的正确结果。
查询用 sceneType=2,不要用 sceneType=4。
type=2 聚合包裹的 send_no 为空;sceneType=4 按晚场发货单号查,通常看不到这组包裹。也不要传 serialNum=1,否则看不到追加行。
打开 SQL 3,确认 @case_name='NORMAL' 后执行准备区。脚本会选择当天无真实订单占用的非自营城市仓,插入 17:00 的 45kg 白场单和 21:00 的 50kg 晚场单,并输出 wareId。
虽然数据库已有晚场单,白场入口只会读取 18:05 前的白场单。此时应只有 1 张 110*45*45,总重45kg。
调用晚场测试接口。预期总重95kg:原 serial1 改成 110*60*60,追加 serial2 小件100*25,两张未出库行的 packageNum=2。
填写 SQL 输出的 wareId 后复制请求。接口用于页面核对,精确字段仍建议同时跑下方数据库断言。
记录行数和 id,再跑一次。第二次不得继续追加,id、serialNum 与推荐都保持不变。
SELECT id, round_no, ware_id, partner_id, serial_num, package_num,
total_weight, item_num, express_status,
package_id, package_info, suggest_pack_id, suggest_pack_info,
data_status, create_time, update_time
FROM xm_bulky_wms_express_package
WHERE round_no = CURDATE()
AND type = 2
AND ware_id = <SQL输出的wareId>
AND partner_id = 0
ORDER BY serial_num, id;
-- 幂等前后比较
SELECT COUNT(*) AS row_count,
GROUP_CONCAT(id ORDER BY id) AS id_list,
GROUP_CONCAT(serial_num ORDER BY serial_num) AS serial_list
FROM xm_bulky_wms_express_package
WHERE round_no = CURDATE()
AND type = 2
AND ware_id = <SQL输出的wareId>
AND partner_id = 0
AND data_status = 0;
白场45kg先把 serial1 设为实际 110*45*45、状态10。晚场后推荐改成110*60*60,实际箱不变,因此匹配状态变2。
白场80kg的87kg箱设为状态20;晚场再加100kg。剩93kg,追加87kg箱和6.1kg箱;已出库旧行任何字段不变。
同品种跨白晚场要追加专用箱。中通总95kg目标3件,从白场1件追加2件,全部无普通箱推荐。
重跑 SQL 3 前,把第一段 @case_name 改成 PACKED、PARTIAL、SPECIAL 或 ZTO。执行准备区,调用白场接口;PACKED/PARTIAL 再执行 SQL 文件里的“白场后置”区;最后调用晚场接口并按文件尾部预期核对。每个场景都要再跑一次晚场接口验证幂等。
07 / COVERAGE
P0 是本次发布必测;P1 是边界、风险和兼容性。可用按钮缩小范围。
| 级别 | ID | 场景 | 关键预期 |
|---|---|---|---|
| P0 | CFG-01 | flowerWeight 列表、保存与校验 | 0、87.00 可保存;null、负数、1000.01、3位小数失败 |
| P0 | DAY-01 | 80kg / 180kg 普通箱拆分 | A 为 1 张最大箱;B 为 87+87+6.1 |
| P0 | DAY-02 | 特殊花材独立装箱 | 普通重量先扣特殊重量;专用箱仍有推荐 id |
| P0 | DAY-03 | 中通100kg | 3件,推荐 id=0,推荐容量=null |
| P0 | DAY-04 | 白场重复执行 | 行数和 id 不变 |
| P0 | PACK-01 | 货架筛选与角标 | 不符筛选仅 T-993;合规筛选含无推荐 T-994 |
| P0 | PACK-02 | 推荐箱直接设箱 | 成功,状态1,无强制留痕 |
| P0 | PACK-03 | 非推荐箱 + forceFlag | 首次6001不落库;force=1成功且仅一条留痕 |
| P0 | PACK-04 | 点击“否” | 只关闭弹窗,不发第二次请求 |
| P0 | PACK-05 | PDA 非推荐箱 | 不返回6001,直接成功,写扫码枪不符留痕 |
| P0 | NIGHT-01 | 45kg + 50kg 主流程 | 49.6箱改87箱,追加13kg箱,总2件 |
| P0 | NIGHT-02 | 状态10重排 | 推荐更新,实际箱不变,变为设箱不符 |
| P0 | NIGHT-03 | 部分已出库 | 按实际箱容量优先扣重,状态20整行不改 |
| P0 | NIGHT-04 | 晚场幂等 | 第二次无更新或追加,id 不变 |
| P0 | NIGHT-05 | 特殊花材跨阶段 | 白场蝴蝶兰 + 晚场蝴蝶兰,共2张蝴蝶兰箱 |
| P0 | NIGHT-06 | 中通晚场 | 总95kg目标3件,追加2件,均无推荐 |
| P1 | EDGE-01 | 0.5 / 6 / 174kg | 最小有效箱、6.1箱、两个87箱且无余箱 |
| P1 | EDGE-02 | 中通冷链硬限制 | expressId=146 + packId 12/17,force=1也不能绕过 |
| P1 | EDGE-03 | 重算后需求变少 | 多余面单保留,不删除、不作废、不清旧推荐 |
| P1 | EDGE-04 | 作废行与序号 | 作废行不参与件数,但新序号从历史最大值继续 |
| P1 | RISK-01 | FHH 更小晚场货位 | 观察是否因 key 改变而重复整组生成,属于已知风险 |
| P1 | RISK-02 | 物流电子面单数量 | 仅隔离配置下测试,避免真实第三方面单副作用 |
08 / EVIDENCE
每条失败必须能回答:输入是什么、接口返回什么、数据库最终是什么、第二次执行是否变化。
接口、请求体、场次、wareId、包裹id。令牌打码,禁止贴完整 JWT。
HTTP 状态、业务 code、msg、records 中的推荐与匹配字段。
id、serialNum、status、实际箱、推荐箱、总重、件数及留痕记录。
提交:0019b5646c3a98e7c813e0cd14a4ba7561ebf89f
环境:test1 / API 实例:________
场次:________ 测试账号:________
白场后台:通过 / 不通过 / 未测
供应商设箱:通过 / 不通过 / 未测
晚场 NORMAL:通过 / 不通过 / 未测
晚场 PACKED:通过 / 不通过 / 未测
晚场 PARTIAL:通过 / 不通过 / 未测
晚场 SPECIAL/ZTO:通过 / 不通过 / 未测
失败用例 ID:________
请求与响应:________
数据库前后快照:________
重跑结果:________
日志关键字:________
结论与阻塞:________
09 / TROUBLESHOOT
大多数“接口没值”不是算法问题,而是日期、场景、序号、分组或缓存没有对齐。
roundNo 与 SQL 的 CURDATE() 是同一天,数据库与应用时区均为 Asia/Shanghai。template_ready、generation_ready 必须为 OK。serialNum:1;它会隐藏追加序号。ware_id>0、single_delivery_flag=0、type=2;TESTADM-A 到 D 不满足。sceneType=2 并传 wareId,不要用 sceneType=4。suggest_pack_id>0,且请求 packId 与推荐 id 不同。/package/pack/finish 或 /finish/change,PDA scan 入口本来就不返回6001。forceFlag=1。Admin 的推荐拆箱 7 条、晚场规划器 10 条目标单测已通过。Supplier 的 PackageLogicFinishTest 当前有 1 失败、1 错误,原因是测试仍断言 PDA 受区域权限限制,并保留了已不再调用的权限 stub;生产代码当前口径是 PDA 必须有物流专员角色,但跳过货区限制。不要把这两个旧断言误判为本需求手工链路失败,手工验收仍需按本页 P0 完整执行。