开放问答
pytest 并行执行下,全局 fixture 共享导致用例互相污染,怎么在 CI 里做到既并行又不串台
该问题的正文、回答与评论。
提问者 谢亦舟-368 · 状态 open
pytestxdist并行测试fixture隔离CI/CD
背景
我维护一条支付清算链路的接口自动化套件(Python 3.11 + pytest 7.4 + httpx,约 1800 条用例),底层连 3 个共享 staging:MySQL 8(同一库)+ Redis 7 + Kafka 3.4。最近为了把回归时长从 52min 压下去,上了 pytest-xdist 8 workers 并行,名义上快 4 倍,实际收益只有 2.3 倍,而且假失败率从 1.7% 涨到 9%——红的用例里,单跑全绿、并行必挂,这是最让我头疼的。
现象(具体可复现)
- 用例 A 下单后写入
orders表 status=PENDING,用例 B 在同一 worker 池里同时跑"取消订单",B 用全局 fixture 里那个固定order_no=ORD_TEST_001做断言,偶尔拿到的是 A 刚写的 PENDING 行——典型的跨用例数据污染; - Redis 里的
token:uid:1001这种全局 key,多个用例共享同一个登录态,A 用例del之后 B 用例就 401; - Kafka 消费组
pay-cb-group在 staging 上被两个 CI 节点同时拉,消费位点互相覆盖,导致"回调通知"用例偶发收不到消息。
已尝试的排查与结果
- 给 xdist 加
--dist loadscope,让同一 class 的 case 落同一 worker:解决了 1 的 ~40%,但跨 class 的污染仍在; - 把全局 fixture 改成
scope=class+ 每个 class 用独立order_no:解决了大部分 1,但 2 的 token 冲突没解决,因为登录态在 Redis 是全局的; - 试过
pytest-split按文件切到 3 台 CI 机器跑:并行度没上去,且 3 的 Kafka 消费组冲突更严重(3 个节点抢同一个 group id)。
期望得到的答案形态
想听到具体可落地的方案,最好带命令 / 配置片段:
- 数据层:每个 worker / 每个 class 用独立 schema(或独立库)+ 事务回滚的最小可行做法,xdist 下怎么把 schema 名注入到 fixture?
- 状态层:Redis / 缓存这类全局态,是 mock 掉、还是给每个 worker 分配独立 key prefix,业界更主流的是哪种?
- 消息层:Kafka 消费组在 CI 并行下的隔离套路(独立 group id?还是改用 consumer offset 直接读?);
- 如果方案太重,并行度只到 3–4 倍但假失败率回到 2% 以内的"次优解"长什么样——我其实更想要这个。
欢迎贴你们的 xdist 配置 + fixture 片段,能贴多少贴多少。
已采纳
回答者
回答正文
评论
暂无评论。