Pytest-xdist并行执行用例时的“坑”

目录

1.背景

2.官网的正常打开方式

3.“坑”之变量保存方式不适用

4.“坑”之用例场景不适用

5.“坑”之日志不全

6.参考资料


1.背景

        用例越来越多,全量执行时间越发长了。这个时候,自然会想到用并行执行的方式。当然,在使用这种方式的前提是,每个用例间是没有耦合和依赖的。

        并行执行的方式也有很多:多进程(pytest-xdist)、多线程(pytest-parallel),另外还有pytest-multithreading。笔者试用了前面两种,在使用pytest-parallel时,不知什么原因,出现大量用例失败。怀疑可能是因为自动化工程结构的原因导致吧。所以,采用了pytest-xdist,不曾想,也是自己挖了“坑”,自己填。。。

2.官网的正常打开方式

        根据官网所述,使用pytest-xdist以后,pytest中fixture所指定的scope是失效的。这会出现:conftest.py中设置为期望仅执行一次为了弥补这一“漏洞”,官网采用“文件锁”的方式来“部分”控制用例执行顺序。

import json

import pytest
from filelock import FileLock

# 这里没有使用autouse=True。自己的脚本场景中如果设置该标记则失败,但同事的脚本场景中使用了也没有问题。怀疑与脚本场景有关,暂无解
@pytest.fixture(scope="session")
# 不用修改传递的这两个参数,这里是固定写好的
def session_data(tmp_path_factory, worker_id):
    if worker_id == "master":
        # 单进程执行
        return produce_expensive_data()

    root_tmp_dir = tmp_path_factory.getbasetemp().parent

    # 生成一个临时文件给所有进程用
    fn = root_tmp_dir / "data.json"
    with FileLock(str(fn) + ".lock"):
        # 当第2个及以后的进程执行用例时,走到这个分支
        if fn.is_file():
            data = json.loads(fn.read_text())
        # 第1个进程走到这里,将生成的数据存到共享文件中
        else:
            data = produce_expensive_data()
            fn.write_text(json.dumps(data))
    return data

3.“坑”之变量保存方式不适用

        官网的代码简洁易用,无奈当前项目工程采用的变量保存方式不合适。

        首先,项目中采用dynaconf的settings.toml进行变量保存。看官可以百度一下,这种.toml格式文件读写json数据是有些麻烦的。也就是存在格式差异。即使在把“data.json”换成“data.toml”,在fn.write_text进行数据保存时,格式也会出现问题。几经失败,只能放弃使用settings.toml保存变量,换用settings.json。(这样会导致工程中大量变量引用需要修改,这个后续再议~~)

        其次,换了settings.json后,初始化产生数据以及数据的写入都没有问题,而新的问题又出现。手动单步调试时,一切OK,直接运行代码出错。后来经过调试发现,第一个进程运行时,将产生的初始化数据保存进文件,正是因为要落盘(写入文件),肯定不如数据在内存中运行快,此时,第二个进程已经运行到读取文件。于是,数据没有完全写入,导致出错。。。。。。

        最后,因为修改了settings.json文件,原有工程中,采用settings.xxx的方式引用变量,就必须全部修改为settings['xxx']。这又是一大工作量~~~

4.“坑”之用例场景不适用

        并行执行用例,并不是所有用例都需要并行的。例如,登录、初始化。官网提供的方式,对全局的conftest.py中的初始化是有效的。但我们的工程中,由于场景设计的特殊性,在一些子模块中有自己局部的conftest.py。而这类初始化,就不适用这样的文件锁方式了。

5.“坑”之日志不全

        综合上述2点,决定放弃pytest-xdist,就用时间换取脚本执行的正确性吧。但又出现了一个问题。代码中没有使用pytest-xdist,只是没有去掉import和安装的库。结果导致运行后,日志中今有setup的日志,其余步骤和最终teardown的日志都没有了。。。卸载了pytest-xdist恢复了正常。至于原因嘛,就不得而知了

6.参考资料

How-tos — pytest-xdist documentation

接口自动化测试:pytest-xdist之session级别的fixture只执行一次 - 走看看

Python测试框架pytest(22)插件 - pytest-xdist(分布式执行)_wangmcn的博客-CSDN博客_pytest-xdist

多线程运行 pytest 用例,解决 pytest-xdist session 级别的 fixture 运行次数不合理和进程切换更消耗 cpu 的问题 · TesterHome pytest-xdist:并发执行用例设计(脱坑)_liwuke的博客-CSDN博客_pytest 并发执行用例

python - Pytest: run teardown once for all workers using pytest-xdist - Stack Overflow 

pytest多进程/多线程执行测试用例_测试小娜的博客-CSDN博客_pytest多线程执行用例 

你可能感兴趣的:(自动化测试,Python,pytest,pytest-xdist,并行)