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

概况:

1、多个接口测试用例单线程执行很慢,需要用pytest-xdist插件提高执行速度;

2、存在session级别fixture,只能执行一次:执行登录等前置操作,获取token等全局数据,如果多次执行,则之前的token会失效

3、pytest-xdist插件没有实现session只执行一次的机智,但提供了文件锁的解决方案,官网:https://www.baidu.com/link?url=diurQHxNUGWze5amBnj_RLJkQvo1-Ls5l2N3Db7HKSamAzRidZDL1LAYl4mxZecP&wd=&eqid=ad97ca9b003dd6f2000000065f9634e9

遇到的问题:

以为官网示例中的参数、方法等都是随便写的伪方法,所以自己想当然的也随意写了,查找资料搞了很久没有解决。

最终解决:

其实,官网给的资料就是解决方案,其中的tmp_path_factory、worker_id等参数都是框架已经实现了的,直接按照示例套用就行

@pytest.fixture(scope="session", autouse=True)
def c_login_fixture(tmp_path_factory, worker_id):
    """执行用例前登录获取token"""
    if worker_id == "master":
        #如果是单线程执行,会走这里的逻辑
        user_account = os.environ["user_account"]
        password = os.environ["password"]
        res = login(user_account, password).json()
        #将token加入到环境变量中,测试用例可以直接从环境变量中取
        token = res["result"]["token"]
        os.environ["token"] = token
        return

    root_tmp_dir = tmp_path_factory.getbasetemp().parent

    fn = root_tmp_dir / "data.json"
    with FileLock(str(fn) + ".lock"):
        if fn.is_file():
            # 从缓存文件中读取token
            token = json.loads(fn.read_text())
            os.environ["token"] = token
        else:
            ## 登录后获取token,写入到缓存文件中
            user_account = os.environ["user_account"]
            password = os.environ["password"]
            res = login(user_account, password).json()

            token = res["result"]["token"]
            fn.write_text(json.dumps(token))
            os.environ["token"] = token
    return

其他问题:

fixture只执行一次的问题解决后,新的问题出现了:

现象:

在用例并行执行过程中,发现部分用例会失败甚至程序抛出异常的问题,进一步排查后发现,是某些接口会不定时的随机请求失败;

将pytest -n 2命令中的线程数调整后发现失败的接口发生变化;

单独把请求失败的接口拿出来请求,没问题

最终问题定位:

业务方面的原因,某些业务接口不支持并发:因为有些数据必需(比如code)唯一,所以同时执行会发生冲突,导致接口失败

解决方案:

1、在特定的接口请求前加延迟,还是会有失败的情况,不稳定;

2、添加重试机制和重试等待时间:--reruns 1 --reruns-delay 2(可以稍微设置大点),参考https://www.cnblogs.com/my_captain/p/12720190.html

posted @ 2020-10-26 10:49  沧海1024  阅读(1607)  评论(1编辑  收藏  举报