接口自动化测试: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