pytest-split不支持多机分发,仅支持单机静态切分;真正可行方案是pytest-xdist配合自定义设备调度,确保环境一致、状态隔离与结果可追溯。

pytest-split 本身不支持多机分发,它只做单机内测试用例的静态切分 —— 这是关键前提。如果你指望它把测试自动发到三台手机或三台远程机器上跑,会直接失败,因为 pytest-split 没有网络通信、节点管理、结果聚合能力。
为什么不能直接用 pytest-split 做多机分发
pytest-split 的设计目标很明确:在单个 pytest 进程启动前,根据已有测试列表(比如从 pytest --collect-only 输出解析)按比例拆成 N 份,每份输出为一个测试 ID 列表,供后续单独执行。它不启动 worker,不监听端口,也不协调远程节点。
常见错误现象包括:
- 执行
pytest --split=3 --partition=1/3后,只在本地跑了一部分用例,另外两台机器完全没反应 - 手动把生成的 ID 列表复制到其他机器上运行,但因 fixture 初始化、全局状态、临时文件路径冲突导致大量失败
- 报告分散在三台机器的本地磁盘,无法合并成一份统一的
allure或JUnit XML
真正可行的多机分发组合:pytest-xdist + 自定义设备调度
要实现“三台手机各跑 1/3 用例”,必须换思路:用 pytest-xdist 作为调度底座,再叠加设备绑定逻辑。核心不是切测试 ID,而是让每个 worker 进程独占一台设备。
实操建议如下:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
立即学习“Python免费学习笔记(深入)”;
- 每台手机对应一个独立的 Appium server 实例,端口不重叠(如
4723、4725、4727),并在device.yaml中固定udid和port - 写一个
conftest.py,在pytest_configure阶段读取环境变量WORKER_ID(pytest-xdist自动注入),然后从设备池里按模选取设备:devices[worker_id % len(devices)] - 所有测试用例必须使用该设备配置启动 driver,且禁止跨用例复用 session —— 否则第二台手机会抢连第一台的 session
- 不要依赖
pytest-split的--partition参数,改用pytest-xdist的--dist=load或--dist=loadscope,让 xdist 动态分配用例到已就绪的 worker
容易被忽略的兼容性陷阱
多机场景下,几个看似无关但致命的点常被跳过:
-
tmp_path在不同机器上路径不一致,但日志、截图若硬编码相对路径,会导致报告里找不到资源 —— 必须用os.path.join(outputs_dir, f"screenshot_{uuid4()}.png")显式构造绝对路径 - Appium server 版本必须一致(比如全是
2.5.0),否则uiautomator2插件行为差异会让同一套用例在某台机器上卡死 -
pytest-xdist默认用execnet通信,而某些云真机平台禁用长连接;此时需改用--tx "ssh=myuser@192.168.1.100"显式指定传输方式,并确保目标机预装了pytest和pytest-xdist - 如果用
allure报告,必须在每台机器上单独生成allure-results目录,最后用allure generate node1/allure-results node2/allure-results node3/allure-results -o allure-report合并,不能指望 xdist 自动聚合
真正的难点不在怎么拆任务,而在怎么让每台机器上的执行环境保持一致、状态隔离、结果可追溯。一旦设备初始化失败或 driver 启动超时,整个 worker 就会卡住,而 pytest-xdist 默认不会自动重试或 fallback —— 这部分得自己用 @pytest.hookimpl(tryfirst=True) 拦截异常并加兜底逻辑。

















