要试的不是函数,是运行中的 HTTP 边界
一句话总结
API 不是一个可调用的 Python 函数,而是在网络边界上通过方法、路径、请求头、JSON、状态码和响应正文共同约定的协议。测试必须把服务器真正启动在一个端口上,并穿过这条边界。
为什么只有纯函数测试还不够
即使 create_order() 返回了正确的字典,路由器也可能没有连接到 POST 路径,可能没有读取认证请求头,也可能把所有异常都转换成 500。正文长度、JSON 解码、内容类型,以及请求头大小写不敏感等行为,在直接调用函数时也看不到。因此,独立评分器会获取一个随机的回环端口,启动 app.py --host 127.0.0.1 --port ...,然后发送真实 HTTP 请求。
创建成功应返回 201;重放同一个命令应返回 200;缺少认证应返回 401;已有身份但权限不足应返回 403;金额无效应返回 400。响应中必须包含新建的整数 ID,以及所有者、组织、金额和状态。每个响应里的 X-Trace-Id 都是把请求与日志关联起来的抓手。只返回正确状态码却发送空正文的实现,以及始终返回同一份静态 JSON 的伪服务器,都会在后续请求中暴露。
在实际项目中形成回归证据
测试会通过 /healthz 等待服务器就绪;如果在时限内仍未就绪,就判定失败。创建完成后,还会使用同一个键和不同金额重试,确认原来的 ID 与金额保持不变;也会沿真实路径验证所有者能否读取和取消刚创建的资源,以及同组织的其他用户、其他组织的管理员是否会被拒绝。进程结束后,还要检查 stdout 与 stderr,确认认证值没有泄露。
实际工作的判断标准
模拟适合用来隔离外部故障,却不能成为协议契约的唯一证据。应同时保留快速的策略单元测试和真实 HTTP 行为测试。下一课会把认证与授权分开,让这条边界判断谁可以对哪个资源执行什么操作。