在用 pytes 做自动化测试的时候,有时候我们的用例会非常多,特别是在用例参数化的时候。很容易就会有上千条的用例。可能每个用例又会有 IO 等待。如果顺序运行的话,就会很耗时。所以希望可以并发运行用例。这时可以用 pytest-xdist。这个网上有很多教程,这里不说了。主要说一下 pytest-xdist 的缺点
pytest-xdist 是多进程运行的,进程切换很耗资源。并发不能调太大。否则会把 cpu 消耗光。如果用 pytest-xdist 同时运行几千个有 IO 等待的用例, 会立刻把 cpu 耗尽。
pytest-xdist 的运行机制破坏了 pytest 对 fixture 原始定义。按照原始的定义,session 级别的 fixture,在一次自动化测试中只会运行一次。但是 pytest-xdist 是每个进程都会运行一次。相当与一些全局性的前置条件会执行多次,在有些情况下可能会有问题的。比如你想在运行所有测试用例之前,先在 session 级别的 fixture 重启测试的程序,pytest-xdist 的每个进程都会执行一次,相当于会重启多次。有可能会出现某些进程已经在运行测试用例了,但另一些进程还在 session 级别的 fixture 里重启服务。影响了测试用例的运行。
为了解决上述问题。我为 pytest 写了这个插件。我把它叫做 pytest-multithreading。有以下好处
先安装 pytest-multithreading。直接输入 pip install pytest-multithreading 安装
运行时用--th 参数指定最大创建的线程数,就可以并发运行测试用例了。
以下是使用示例
import time
import pytest
test_data_list = [i for i in range(1,1000)]
@pytest.mark.parametrize("i",test_data_list)
def test_multithreading(i):
time.sleep(2)
assert 1 == 1
if __name__ == "__main__":
#--th是指定最大线程数,即最大并发运行的用例。这1000个用例会并发运行
pytest.main(["test_pytest.py","-x","--th=1000"])
我们知道如果想要并发运行测试用例。就要让所有的用例都没有依赖关系,每个用例不能干扰其它用例的运行。但是有些用例要 reload 程序,这会干扰其它用例的运行。所以要让这些用例独立运行,不能让其参与并发运行。所以 pytest-multithreading 做了这个支持标记那些用例不并发运行的功能
使用示例如下:
import time
import pytest
test_data_list = [i for i in range(1,100)]
@pytest.mark.parametrize("i",test_data_list)
def test_multithreading(i):
print("test_concurrent")
#被@pytest.mark.notconcurrent标记的用例不会参与并发运行,并发运行的用例会等这些被标记的用例运行结束后才开始并发运行
@pytest.mark.notconcurrent
def test_notconcurrent():
print("test_notconcurrent")
time.sleep(10)
if __name__ == "__main__":
pytest.main(["test_pytest.py","-x","--th=100","-s"])
一开始写 pytest-multithreading 的时候,是为了可以更高并发的运行 pytest 的用例。那时还不知道其实已经有 pytest-parallel 这个支持多线程运行用例的插件了。它们两个的对比如下:
1.pytest 的-x 参数失效了。pytest 原有的功能如果输入-x 参数时,如果有一个用例失败时,pytest 会立刻停止运行。但是启用了这两个插件后,pytes 会运行完所有用例。
2.启用这两个插件后,allure-pytest 生成的测试报告将无效
3.pytest-multithreading 比 pytest-parallel 有一个优点。pytest-paralle 运行 session 级别的 fixture。每个线程都会运行一次。这是和 pytest-xdist 同样的问题。而且如果 session 级别的 fixture 是有 IO 等待的话。pytest-paralle 执行用例的总时长将会大大增加
虽然 pytest-multithreading 有以上缺点,但是我还是觉得它对我的工作是很有帮助的。因为我有几千个有 IO 等待的用例需要经常运行。这个时候 pytest-multithreading 能够最快的帮我运行完。总结起来说就是 pytest-multithreading 的适用场景是有很多有 IO 等待的用例需要快速运行。以后再找时间兼容下 allure-pytest 插件和-x 参数的问题