Files
xst 52b73f456c refactor(api): yun8_sync 并入 tests 分层框架(接口层 apis/yun8 + 用例层 api + Allure)
- tests/core: 新增 BaseHttpClient 统一 HTTP 封装(直连绕行/超时/日志/自定义编码);
  db_helper 追加 Db 长连接类(事务/mogrify/自动重连),既有函数不动
- tests/apis/yun8: 21 个 step 方法按域拆分为 5 个 Mixin(driver/accounting/
  audit_payment/receipt/third_party),Yun8Pipeline 24 步编排原样迁移,
  SQL 全部参数化并集中至 sql_templates
- tests/api: 5 阶段有序 P0 E2E 用例(业务失败由 print 改为真实报错)+
  README 迁移(删除明文密码段,修正步骤编号漂移)
- yun8_sync 目录退役:配置并入 test_config.yaml 的 yun8_api 段;
  造数 CLI 保留(python -m tests.apis.yun8.cli,兼容旧 config.yaml 结构)
- pytest.ini 注册 api/yun8_sync marker;requirements.txt 补 requests>=2.28
- 静态验证: compileall / 全仓 collect 24 条 / marker 过滤 / CLI --help /
  客户端与 pipeline 离线实例化 / SQL 占位符核对 / cross_end 兼容
2026-09-08 11:38:17 +08:00
..

yun8 运输流程 API 造数(接口自动化)

将 yun8.postman_collection.json 中 "运输流程" 全部 18 个接口 + SQL 写入实现为 pytest 用例 + 造数 CLI,与 tests/ 框架分层对齐(apis/ 接口层 ≙ pages/ PO 层)。

⚠️ 本套件会真实调用测试环境接口并写入数据库(造运单、打款、回单、ETC 发票), 使用 yun8_sync marker 隔离,不会混入默认冒烟扫描。


分层结构

tests/
├── apis/yun8/                 # 接口层(≙ pages/ PO 层)
│   ├── client.py              #   Yun8ApiClient 门面: 司机/管理/滇运通 3 套会话
│   ├── driver_api.py          #   step01-05 司机端接口
│   ├── accounting_api.py      #   step06-09 运费核算
│   ├── audit_payment_api.py   #   step10-16 审核 & 付款
│   ├── receipt_api.py         #   step17-20 回单/上报
│   ├── third_party_api.py     #   step21 滇运通(独立 host/token)
│   ├── sql_templates.py       #   全部 SQL(参数化,%s 占位)
│   ├── pipeline.py            #   Yun8Pipeline 24 步编排(Postman 变量上下文)
│   └── cli.py                 #   造数 CLI(python -m tests.apis.yun8.cli)
├── api/                       # 用例层
│   ├── conftest.py            #   yun8_config / yun8_db / yun8_pipeline fixtures
│   └── test_yun8_transport_flow.py   # P0 E2E: 5 个有序阶段用例
└── config/test_config.yaml    # yun8_api 配置段(数据库复用 database 段)

流程概览

┌─────────────────────────────────────────────────────────────────┐
│ 阶段 A: 司机端 (Step 01-05)                                      │
│ 查询货源 → 接单 → 查询待运输单 → 装货 → 卸货                       │
│ 变量: mainOrderCode → code / vehicleCode / orderCode             │
├─────────────────────────────────────────────────────────────────┤
│ 阶段 B: 运费核算 (Step 06-09)                                    │
│ 查询运单 → 运单详情 → 核算试算 → 核算提交                         │
│ 变量: 30+ 核算字段 + ticketImageUrls                             │
├─────────────────────────────────────────────────────────────────┤
│ 阶段 C: 审核 & 付款 (Step 10-16)                                 │
│ 查询审核 → 审核通过 → 队长分账(可选) → 油卡充值 → 司机打款 → 货主打款│
├─────────────────────────────────────────────────────────────────┤
│ 阶段 D: 回单文件 + SQL (Step 17-21)                              │
│ 运单上传(payNo) → 打款记录 → 文件名前缀 → INSERT → 上报运单        │
├─────────────────────────────────────────────────────────────────┤
│ 阶段 E: ETC 开票 SQL (Step 22-24)                                │
│ 写入 base_etc_invoice (多条) → 写入 tms_order_etc_push           │
│ → 更新 tms_order_detail 开票状态                                 │
└─────────────────────────────────────────────────────────────────┘

上下游变量传递

步骤 产出变量 消费步骤
01 查询货源 mainOrderCode, residueNumber 02, 09
03 查询待运输单 code, vehicleCode, orderCode 04-24
06 运费核算 30+ 字段 (branchCode, oilFee, ...) 09, 12
07 运单详情 deliveryCashFee, driverActualFreight, ... 09, 15
08 核算试算 ticketImageUrls 09
17 运单上传 payNo (sendMsg 正则提取) SQL
18 打款记录 所有 code 19
19 文件名前缀 filePrefix SQL

使用

pytest 用例(5 阶段有序 E2E,带 Allure 报告与断言)

# 完整流程(5 个阶段用例,前置失败自动 skip 后续)
pytest tests/api -m yun8_sync -v

# 生成 Allure 报告
allure generate output/allure-results -o output/allure-report --clean

阶段与用例对应: A 司机端 / B 运费核算 / C 审核付款 / D 回单+SQL / E ETC 开票。 execute_after_audit=false 时 D、E 阶段自动 skip。

造数 CLI(循环造数 / 分阶段运行)

# 完整流程
python -m tests.apis.yun8.cli --auth-driver "Bearer xxx" --auth-admin "Bearer yyy"

# 仅司机端 (Step 01-05) / 仅核算 (06-09) / 仅审核付款 (10-16) / 仅回单+SQL+上报 (17-24)
python -m tests.apis.yun8.cli --stage driver
python -m tests.apis.yun8.cli --stage accounting
python -m tests.apis.yun8.cli --stage payment
python -m tests.apis.yun8.cli --stage receipt

# 循环执行 10 次,每次间隔 5 秒
python -m tests.apis.yun8.cli --repeat 10 --delay 5

# 仅 receipt 阶段循环 100 次
python -m tests.apis.yun8.cli --stage receipt --repeat 100 --delay 2

# 预览 SQL 不写库(配合 random 重量模式,每次自动换新重量)
python -m tests.apis.yun8.cli --dry-run
python -m tests.apis.yun8.cli --repeat 5 --dry-run

⚠️ --dry-run 不是只读模式:仅跳过回单/ETC 的 SQL 写入(打印 mogrify 渲染的 SQL),HTTP 步骤仍真实执行,driver 阶段的 reset SQL 也不受 dry-run 影响。

独立运行 payment 或 receipt 阶段时,会自动从 admin 端补全前置数据 (code/orderCode),无需手动指定。

配置

统一在 tests/config/test_config.yaml 的 yun8_api: 段维护:

  • tokens: 司机端/管理端 Bearer Token(CLI --auth-driver / --auth-admin 可覆盖)
  • driver_params: 重量模式(fixed 固定值 / random 每次随机 1.0~10.0)、 装卸货经纬度覆盖、待运输单重置、装卸货照片 URL
  • accounting: 核算固定参数 + execute_after_audit(是否执行 12-21 步)
  • payment: 打款参数;etc_invoice: ETC 发票条数
  • dianyuntong.enabled: 滇运通审核开关(默认关闭)

branchCode / businessTypeCode / payeeCode / shipmentPhone / shipmentPartyCode 优先从 step06 返回值读取,配置仅作兜底。


故障处理

现象 处理方式
WAF 拦截 (SQL注入误判) 已内置:直连服务器(trust_env=False)+ 手工 query string 编码
"运单正被处理中" 已内置:自动重试 5 次,间隔递增 5~13s
"货运单不存在" Token 过期或运单状态不对,检查 admin token
业务 code≠0 会直接失败(迁移后行为):CLI 计入失败循环,pytest 用例 RED
提取不到 payNo 会直接失败(迁移后行为):不再写空 front_seq_no 的脏行
独立阶段提示 code 为空 已内置:自动从 admin 端补全
日志 output/logs/test_run_*.log(DEBUG 全量 URL,含 WAF 排查线索)

接口对照表

(Step 编号与 tests/apis/yun8 代码中的 stepNN 方法一一对应)

Step 名称 方法 路径 Auth
01 查询货源 GET /ntocc-tms-api/order/orderHallList Driver
02 接单 POST /ntocc-tms-api/orderDetail/receive Driver
03 查询待运输单 GET /ntocc-tms-api/orderDetail Driver
04 装货 PUT /ntocc-tms-api/orderDetail/fill Driver
05 卸货 PUT /ntocc-tms-api/orderDetail/uploadTicketImage Driver
06 运费核算查询运单 GET /ntocc-tms-api/orderDetail/orderDetailHandlePageList Admin
07 查询运单详情 POST /ntocc-tms-api/orderDetail/getOrderDetailExpensesParamList Admin
08 核算试算 PUT /ntocc-tms-api/orderDetail/calculateOrderDetail Admin
09 核算提交 PUT /ntocc-tms-api/orderDetail/orderHandleEditSubmitHandle Admin
10 查询运单审核 GET /ntocc-tms-api/orderDetail (status=6&isSettle=1) Admin
11 核算审核通过 POST /ntocc-tms-api/orderDetail/auditOrderDetail Admin
12 队长分账预览 GET /ntocc-tms-api/orderDetail/captainSplitAdjustPreview/{code} Admin
13 队长分账调整 POST /ntocc-tms-api/orderDetail/adjustCaptainSplit Admin
14 单油卡充值 POST /ntocc-tms-api/finance/singleOil Admin
15 垫资-财务打款 POST /ntocc-tms-api/arpaTransfer/payToDriver Admin
16 垫资-货主打款 POST /ntocc-tms-api/orderDetail/applicationForPayment Admin
17 查询运单上传(提取 payNo) GET /ntocc-basic-api/dytBusiness/orderDetail (status=5) Admin
18 查询打款记录 GET /ntocc-tms-api/remitDefinite Admin
19 查询文件名前缀 GET /ntocc-tms-api/centralizedPayment/downLoadElectronicReceipt Admin
20 上报运单 POST /ntocc-basic-api/dytBusiness/reportOrderDetail Admin
21 滇运通审核 POST https://yndyt.cxtech.vip/ntocc-tms-api/orderDetail/updateOrderDetailExt 滇运通
— 回单 SQL INSERT — ntocc.base_gd_mft_file —
22 ETC 开票信息写入 SQL INSERT ntocc.base_etc_invoice —
23 ETC 推送记录写入 SQL INSERT ntocc.tms_order_etc_push —
24 运单 ETC 开票状态更新 SQL UPDATE ntocc.tms_order_detail —

步骤 22 每个运单插入 etc_invoice.count 条发票(config.yaml 配置,默认 3),每条的 发票号码(随机 20 位数字)、金额(随机分配,所有发票合计 ≤ 运费×50%,运费 优先取 driverActualFreight、缺失时取 shipmentActualFreight,超限或运费未知则跳过 发票写入)、进站/出站(按广东→河北路段链取相邻两站)、时间(交易时间在运单窗口 内逐条推进)各不相同;税额、开票方、发票类型、URL 等其余字段用固定值。 步骤 22/23 的 order_code/order_no 取步骤 03 的 orderCode,push_order_no 为其后 追加 -1,order_detail_code 取步骤 03 的 code,两个表的 code 按现有数据规则 (32 位十六进制)自动生成,随 receipt 阶段执行(--dry-run 仅预览不写库)。 步骤 23 的推送记录固定写入 invoice_pull_status=2、start_status=1、end_status=1、 start_result='成功'、end_result='成功';步骤 24 将步骤 03 orderCode 对应运单的 etc_invoice_status 置为 3。