根本原因是装错包:pytest-xdist与xdist是两个不同包,pip install xdist会安装错误包导致ImportError,必须用pip install pytest-xdist并验证pip show pytest-xdist输出。

pytest-xdist 安装错包导致 ImportError
根本原因不是“没启用插件”,而是压根没装对——pytest-xdist 和 xdist 是两个不同包。pip install xdist 会装一个空壳或旧版,运行时直接报 ImportError: No module named 'xdist'。
- 必须用
pip install pytest-xdist(注意中间有短横) - 装完立刻验证:
pip show pytest-xdist,确认输出里有Name: pytest-xdist - 若项目用
pyproject.toml,确保dependencies或[build-system]中写的是pytest-xdist,不是xdist - 虚拟环境里要确认
which pytest和which python指向同一环境,否则可能装到全局而非当前环境
-n auto 启动后实际只跑 1 个 worker
-n auto 并非“尽量多开”,而是取 os.cpu_count() - 1;但真实并行数还受测试本身限制——只要存在资源冲突,pytest-xdist 就会退化为串行或卡死。
- 硬编码端口(如
8000):多个 worker 同时 bind 失败,进程阻塞或退出 - 共享文件路径(如固定写
/tmp/test.db):各 worker 覆盖彼此数据,触发锁等待 - 全局状态修改(如模块级变量、未隔离的数据库连接池):worker 间互相污染
- macOS M 系列芯片上部分 Python 版本识别逻辑核数异常,
os.cpu_count()返回值不准,建议显式用-n 2或-n 4 - CI 环境(如 GitHub Actions)默认仅分配 2 核,
-n auto实际只起 1 个 worker,需查 CI 配置再调
测试间资源撞车导致并发失效
pytest-xdist 把测试分发到独立子进程,它们不共享内存,但默认共用工作目录、环境变量、文件系统和网络栈——所有外部资源都可能撞车。
- 数据库:别用文件 SQLite,改用
sqlite:///file::memory:或带随机后缀的路径,如test_{os.environ.get('PYTEST_XDIST_WORKER')}.db - 临时文件:用
tempfile.mkstemp(prefix=f'test_{os.getpid()}_'),避免tmpdir被多进程复用 - HTTP 服务:端口设为
0让系统自动分配,例如http.server.HTTPServer(('', 0), handler) - 日志/配置加载:每个 worker 初始化自己的 logger 实例,别复用全局 logger 对象
--dist=loadgroup 不生效或负载不均
--dist=loadgroup 不是“自动分组”,它按 class 名或 @pytest.mark.xdist_group(name="xxx") 分组调度;没显式标记或 class 内部方法强耦合时,仍可能被拆散。
立即学习“Python免费学习笔记(深入)”;
- 若某
TestAPI类中test_login和test_get_profile共享 token,必须加@pytest.mark.xdist_group(name="api"),否则--dist=loadgroup默认按 class 名分组也无效 - 组太大(如单个 class 含 50+ 方法)会导致某个 worker 过载,总耗时反而上升,应拆分或加更细粒度标记
- fixture 作用域在分布式下失效:即使
@pytest.fixture(scope="session"),每个 worker 仍会独立执行一次,不能靠它共享初始化结果
真正让 pytest-xdist 并行跑起来,难点不在启动命令,而在测试代码是否天然支持隔离——任何对外部状态的隐式依赖,都会在多进程下暴露出来。


















