pytest-xdist的-n参数不生效主因是未显式安装插件(pip install pytest-xdist),或环境/版本不兼容;实际并行需避免共享资源,推荐用--dist=loadgroup按标记分组调度以保状态依赖。

为什么 pytest-xdist 的 -n 参数不生效?
常见现象是运行 pytest -n 4 后,实际仍单进程执行,或报错 ModuleNotFoundError: No module named 'xdist'。根本原因是未正确安装或导入插件。
- 必须显式安装:
pip install pytest-xdist(仅装pytest不够) - 安装后无需 import,pytest 会自动加载,但需确认版本兼容:Python 3.7+ 推荐用
pytest-xdist>=2.5.0 - 检查是否被禁用:某些
pytest.ini或pyproject.toml中含addopts = --disable-warnings类配置,可能意外屏蔽插件;可临时加--trace-config查看插件加载列表
如何让测试函数真正并行执行而不互相干扰?
pytest-xdist 默认按模块(module)或测试函数(test function)切分任务,但若多个测试共用全局状态(如修改 os.environ、写同一临时文件、操作共享数据库连接),就会出现竞态或失败。
- 避免全局副作用:每个测试应独立准备/清理环境,优先用
tmp_pathfixture 而非硬编码路径 - 禁用跨进程共享资源:例如
logging.basicConfig()在 conftest.py 中调用会导致多进程争抢 stdout;改用caplog或为每个测试单独配置 logger - 数据库类测试务必使用事务回滚或 per-test 隔离库名(如加
test_{worker_id}后缀),否则pytest -n 2可能两个进程同时 truncate 同一张表
--dist=loadgroup 和 --dist=load 有什么实际区别?
默认 -n 使用 --dist=load(动态负载均衡),但对耗时差异大的测试集效果不佳;--dist=loadgroup 更适合按标记分组调度。
-
--dist=load:master 进程把下一个待执行的 test item 分发给空闲 worker,适合所有测试耗时接近的场景 -
--dist=loadgroup:需配合@pytest.mark.xxx使用,例如标记@pytest.mark.slow的测试会被打包成一个 group,由单个 worker 串行执行,避免慢测试阻塞其他 worker;启用方式:pytest -n 4 --dist=loadgroup -m "slow" - 注意:若未打标记就用
loadgroup,所有测试会被当成一个 group,退化为单进程
CI 环境中 pytest-xdist 常见崩溃原因
在 GitHub Actions、GitLab CI 等容器环境中,pytest -n auto 可能因误判 CPU 数量而开过多进程,导致 OOM 或超时。
立即学习“Python免费学习笔记(深入)”;
- 不要用
-n auto:容器通常报告宿主机 CPU 数,而非分配值;明确指定数值,如-n 2 - 限制内存敏感操作:若测试含大文件读写或图像处理,多进程会放大内存压力;可在
conftest.py中通过os.getenv("PYTEST_XDIST_WORKER")检测是否为 worker 进程,针对性降级资源用量 - Windows CI 需额外注意:默认 spawn 方式不支持某些全局 fixture 初始化,建议 CI 统一用 Linux runner,或加
--boxed(但会显著降低性能)
-n 数字。最易被忽略的是环境变量和临时目录的隐式共享——哪怕只有一处没清理,就可能导致 80% 的并行收益归零。


















