江西206单人单电脑Apifox全流程与压测方案

日期:2026-08-23
条件:1名执行人员、1台Windows电脑、Apifox
服务地址:http://192.168.0.11:8080,执行前再次确认
说明:原多点位网络测试方案保留,本方案用于先复现业务接口表现,不能单独定位具体网络区段

1. 本次分成两项

  1. 全流程测试:按真实设备调用顺序,串行跑通消费机、绑盘/450取餐和称重台流程。
  2. Apifox压测:将已通过的请求复制到压力场景,观察客户端耗时、错误率和服务端runtime

全流程未通过前不进行压测。生产环境禁止压测真实扣款、批量绑盘和批量就餐数据写入。

2. Apifox环境变量

在Apifox新建环境“江西206-现场测试”,只在本地保存敏感参数:

变量 说明
baseUrl http://192.168.0.11:8080
consume_code 测试消费机编号
bind_code 测试绑盘机编号
weigh_code 测试称重台编号
staff_uuid 测试人员UUID
card_id 测试卡号,只允许测试账户
plate_code 可清理的测试餐盘编号
left_dishes_uuid 当餐测试菜品UUID
right_dishes_uuid 双称设备右侧菜品UUID,单称为空
api_account/api_pwd/api_key 消费接口认证参数,不写入公共文档
msgid 每笔消费动态生成
create_time 每次请求动态生成

将以下脚本放到集合级前置脚本,或分别放到zhctPushMealorderPay请求前:

const d = new Date();
const pad = n => String(n).padStart(2, '0');
const createTime = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
pm.environment.set('create_time', createTime);
pm.environment.set('msgid', `${pm.environment.get('consume_code')}${Date.now()}`);

3. 关键流程接口总表

顺序 场景 接口 类型 主要作用 是否适合生产压测
1 公共 POST /p/api/equipmentStart 写状态 设备启动并读取运行配置 仅低频
2 公共 POST /p/api/heartbeat 轻量写状态 设备心跳、读取餐次等状态 适合低压安全探测
3 菜谱 POST /p/api/getMeal 查询 获取当餐菜谱,卡顿页面的关键接口 适合压测
4 称重台 POST /api/weigh/pushDishes 写数据 给称重台左/右称排菜 仅测试设备低频
5 称重台 POST /api/weigh/pushWeight 写数据 上传左右称当前重量 仅测试设备受控压测
6 绑盘 POST /p/api/selectPlate 查询 查询餐盘是否已绑定及绑定信息 适合测试餐盘低压
7 绑盘 POST /p/api/bindPlateInfo 创建绑定/订单 绑定人员和餐盘并返回人员、余额、营养数据 不批量压生产
8 450取餐 POST /p/api/zhctPushMeal 创建就餐数据 按餐盘绑定关系写入菜品重量和订单金额 不压生产
9 营养 POST /p/api/currentMealNutrition 查询 验证当餐累计金额和营养变化 适合测试人员低压
10 消费机 POST /api/consume/orderPay 扣款/创建订单 消费机在线或离线订单结算 严禁生产压测

4. 全流程测试

4.1 流程A:基础连接和菜谱

按顺序执行:

  1. POST /p/api/equipmentStart
    • Body:x-www-form-urlencoded
    • 参数:code={{weigh_code}}
    • 断言:HTTP 200、body.code=0、记录trace_id
  2. POST /p/api/heartbeat
    • 参数:code={{weigh_code}}
    • 断言:HTTP 200、body.code=0
  3. POST /p/api/getMeal
    • Body:form-data
    • 参数:category=truekeyword=code={{weigh_code}}
    • 断言:HTTP 200、body.code=0data包含当餐菜品。

该流程用于确认设备启动、心跳和卡顿页面的菜谱请求是否正常。

4.2 流程B:称重台排菜和重量上报

  1. POST /api/weigh/pushDishes
    • Body:x-www-form-urlencoded
    • 参数:code={{weigh_code}}left_dishes_uuid={{left_dishes_uuid}}right_dishes_uuid={{right_dishes_uuid}}
    • 断言:body.code=0、message包含“排菜成功”。
  2. POST /api/weigh/pushWeight
    • 参数:code={{weigh_code}}left_dishes_weight=5000right_dishes_weight=0
    • 断言:body.code=0、message包含“上传成功”。
  3. 再次调用pushWeight,将测试重量改为较小值,用于模拟取餐后的重量变化。

注意:pushWeight控制器实际读取的是设备编号和左右重量;菜品UUID来自前一步排菜状态。必须使用专用测试设备编号,避免改动现场真实称重台状态。

4.3 流程C:绑盘到450取餐

  1. POST /p/api/selectPlate
    • 参数:plate_code={{plate_code}}
    • 目标:确认测试餐盘当前状态。
  2. POST /p/api/bindPlateInfo
    • 参数:staff_uuid={{staff_uuid}}plate_code={{plate_code}}equipment_code={{bind_code}}dishes_uuids=["{{left_dishes_uuid}}"]
    • 断言:body.code=0,返回人员、余额、绑定ID和营养数据。
  3. POST /p/api/zhctPushMeal
    • 参数:code={{plate_code}}equipment_code={{weigh_code}}
    • dish_info为JSON字符串,包含当前时间和测试菜品重量。
    • 断言:body.code=0、message包含“推送成功”。
  4. POST /p/api/currentMealNutrition
    • 参数:staff_uuid={{staff_uuid}}
    • 断言:body.code=0,累计金额/营养变化与测试重量一致。

dish_info示意:

{"create_date":"{{create_time}}","details":[{"uuid":"{{left_dishes_uuid}}","weight":"50"}]}

该流程会创建绑盘订单和就餐数据。每轮必须使用可清理测试餐盘,并在下一轮前确认餐盘绑定和订单数据已清理或已完成业务闭环。

4.4 流程D:消费机消费

  1. POST /p/api/equipmentStart
    • 参数:code={{consume_code}}
  2. POST /p/api/heartbeat
    • 参数:code={{consume_code}}
  3. POST /api/consume/orderPay
    • Body:JSON。
    • 使用测试card_id或测试staff_uuid,金额建议0.01元且必须能够退款。
    • 每次请求由前置脚本生成唯一msgidcreate_time
    • 认证字段从Apifox私有环境变量读取。
    • 断言:HTTP 200、body.code=0、返回order_notrace_id
  4. 用相同msgid立即再提交一次。
    • 断言:在线订单应被防重拦截,不能生成第二笔订单。

消费成功后必须核对订单、余额变化并完成退款。未确认测试账户和退款方案前,不执行本流程。

5. 全流程记录表

Apifox每个请求保存以下结果:

流程 接口 开始时间 HTTP状态 Apifox总耗时 body.code trace_id 服务端runtime 结果

流程通过条件:

6. Apifox压测分组

6.1 场景P0:单请求基线

每个接口连续执行20次,记录p50、p95、p99、最大耗时和错误率。先确认单请求稳定,再进入并发测试。

6.2 场景P1:安全查询与心跳混合场景

推荐在生产闭餐时段执行:

接口 权重
/p/api/heartbeat 50%
/p/api/getMeal 30%
/p/api/currentMealNutrition 20%

阶梯:1 -> 5 -> 10 -> 20 -> 50 -> 100 VU。每档爬坡1分钟、保压5分钟;只有上一档错误率和服务器指标正常才进入下一档。VU只是工具并发数,最终结论以实际RPS为准。

6.3 场景P2:称重台重量上报

只允许使用专用测试weigh_code

该场景会持续写设备重量和历史记录,测试后需要核对并清理测试数据。

6.4 场景P3:状态型业务接口

bindPlateInfozhctPushMeal需要大量独立测试餐盘、人员和清理脚本;orderPay还涉及真实扣款、防重和退款。因此:

7. Apifox压力测试配置

每个压力场景至少配置:

推荐停止条件:

8. 如何判断结果

结果 判断
Apifox耗时高,服务端runtime 优先看网络传输、连接建立、响应回程或Apifox电脑排队
Apifox耗时和服务端runtime都高 优先看应用、PHP-FPM、数据库和服务器资源
单接口稳定、混合场景异常 看连接数、接口资源竞争和服务端队列
低VU正常、高VU错误且Apifox CPU高 压测电脑可能先达到瓶颈,不能直接判服务器容量不足
getMeal单独出现长尾 重点查菜谱查询逻辑、响应体大小和对应SQL
pushWeight正常、zhctPushMeal 网络基础请求未必异常,重点查就餐写入和下游同步逻辑
同一msgid生成多笔消费订单 防重失效,立即停止消费场景

9. 一个人的实际执行顺序

  1. 准备测试设备、人员、卡、餐盘、菜品和清理方案。
  2. 在Apifox导入项目OpenAPI,建立私有环境变量。
  3. 串行执行流程A、B、C、D,保存每个trace_id
  4. 查询服务端日志,对齐Apifox总耗时和服务端runtime
  5. 执行P0单请求基线。
  6. 闭餐时段执行P1安全混合压测。
  7. 使用专用测试称重台执行P2。
  8. 不在生产并发执行P3;确有需要时另建隔离环境和数据集。
  9. 输出p50/p95/p99、RPS、错误率、客户端与服务端耗时差及异常trace_id。

10. 本方案边界

单电脑Apifox可以判断接口功能、长尾、并发下错误率,以及客户端与服务端处理耗时是否一致;但它不能精确判断故障位于哪台交换机、哪段跨地区链路,也不能排除压测电脑自身成为瓶颈。若复现出稳定异常,再启用原多点位网络测试方案进行分段定位。