前言:

试想一下1000条用例,每条用例1s全部线性执行下来都要十几分钟, 如果改用多线程执行,开十个线程一分多钟就可以搞定, 这是多大诱惑。啃了几天终于也是拿下了多线程,虽然学会了,最终却发现项目上不适用,无奈下只能放弃。

 

如何使用多线程?

安装:pip install pytest-xdist

使用1:-n=线程数

import pytest


class TestCase:
    def test_001(self):
        print('用例1')

    def test_002(self):
        print('用例2')

    def test_003(self):
        print('用例3')


if __name__ == '__main__':
    pytest.main(['-s', '-n=3', '--dist=loadscope', './test_001.py'])

执行结果:

gw0 I / gw1 I / gw2 I 
gw0 [3] / gw1 [3] / gw2 [3]

...

执行结果解析:使用多线程不会打印程序内容 gw0 I / gw1 I / gw2 I 说明它起了三个线程, gw2 [3]  这个 [3] 说明有三条用例, ...三个点说明三条用例都执行成功

 

使用2:-n=auto

if __name__ == '__main__':
    pytest.main(['-s', '-n=auto', './test_001.py'])

执行结果:

gw0 I / gw1 I / gw2 I / gw3 I / gw4 I / gw5 I
gw0 [3] / gw1 [3] / gw2 [3] / gw3 [3] / gw4 [3] / gw5 [3]

...

执行结果解析:系统自动根据CPU核心分配线程数来执行用例,我的电脑是6核心,它分配了5个线程来执行,另外的那个被别的程序占用了。 

 

多线程它分三种执行方式:

  --dist=loadscope:按模块来执行用例,也就是一个线程执行一个模块(class)

  --dist=loadfile:按测试文件执行用例,也就是一个线程执行一个测试文件(file)

  默认顺序:如果什么都不写, 则默认是以单独的测试用例来执行,也就是一个线程执行一个用例(case)

 

使用方式:

if __name__ == '__main__':
    pytest.main(['-s', '-n=auto', '--dist=loadscope', './test_001.py'])

知道是这么使用就可以了,执行结果就不解析了

 

问题:

问题1:conftest.py文件里的内容, 也被多次执行了, conftest.py放的是登录等前后置方法,多次执行这不是我想要的,怎么解决?请看以下conftest.py文件中的代码,有注释,很简单, 直接套用就行。

将以下代码复制粘贴到conftest.py文件中,“print('写你的函数方法,例如:登录')” 标记有这个的地方,就是可以修改的地方,其余地方不能修改

import json

import pytest
from filelock import FileLock


# PC端登录
@pytest.fixture(autouse=True, scope="session")
# tmp_path_factory, worker_id: 不用修改传递的这两个参数,这里是固定写好的。函数名称可以自定义【不可删除,修改】
def login_request(tmp_path_factory, worker_id):
    # 如果是单线程执行,则走该分支【不可删除、修改】
    if worker_id == "master":
        print('写你的函数方法,例如:登录')

    # 如果是多线程执行,则走以下分支:获取所有子节点共享的临时目录【不可删除、修改】
    root_tmp_dir = tmp_path_factory.getbasetemp().parent
    # 生成一个临时文件给所有进程用【不可删除、修改】
    fn = root_tmp_dir / "data.json"
    with FileLock(str(fn) + ".lock"):
        # 当第2个及以后的进程执行用例时,走到这个分支【不可删除、修改】
        if fn.is_file():
            pass
        # 第1个进程走到这里,将生成的数据存到共享文件中
        else:
            # 登录方法_pc
            data = print('写你的函数方法,例如:登录')
            fn.write_text(json.dumps(data))

 

 

好了, 来说明一下为啥不建议使用多线程了

使用多线程时, 你的用例之间的依赖必须是独立的,就是用例1不能用用例2的变量,否则执行就会出现异常,其实这一条规则足以将大部分学者劝退,因为项目上不可能一条用例分配一个测试账号来设计。