Web自动化中多浏览器并发
一、背景
1、当自动化用例比较多时,执行需要很长时间,为了提高执行效率可以将用例分配到多个浏览器执行
2、兼容性测试,在多个不同的浏览器上执行自动化用例,测试这些用例在不同浏览器上是否正常
二、设计方案
1、使用pytest-xdist插件
2、执行用例的时候,框架需要知道执行哪些浏览器
- 可以在pytest执行时,指定一个命令行参数,--browsers,表示要执行的浏览器名称,多个浏览器用逗号分隔
--browsers=chrome,chrome
或者
--browsers=chrome,edge
- 定义命令行执行参数,需要进行代码处理才会被pytest识别
# 这是pytest的内置钩子函数,名称是固定的 # 可以用来自定义命令行参数 def pytest_addoption(parser): parser.addoption('--browsers',action='store')
- 如何将用例分配给不同进程
- 得到多个浏览器名称,字符串为"chrome,chrome",为了更好的处理,可以将字符串转化为列表["chrome","chrome"]
- 第一步得到列表有索引,索引从0开始,进程id(gw0,gw1,gw2......),刚好对应上索引,所以我们可以按照索引的位置去对应传递浏览器名称到对应的进程上
- 解析进程id里的数字,和列表索引对应起来,获取对应索引代表浏览器名称
- 代码在conftest实现
# 获取浏览器名称 @pytest.fixture(scope='session',autouse=True) def get_browser(request,worker_id): # 得到--browsers对应的值 browsers = request.config.getoption('--browsers') if browsers: # 'chrome,chrome' browsers_list = browsers.split(',') # ['chrome','chrome'] if worker_id=='master': return browsers_list[0] else: # gw0/gw1/gw2... index = int(worker_id[2:]) return browsers_list[index] else: return 'chrome'
- 将得到的浏览器名称传递到初始化代码
@pytest.fixture(scope='session',autouse=True) def init_driver(get_browser): browser = get_browser DriverOperate.globalDriverOperate = DriverOperate(browser=browser) DriverOperate.globalDriverOperate.get('url') BuyerLoginActions().buyer_login(username='username',password='password') yield DriverOperate.globalDriverOperate.quit()
- 分配不同的用例给不同的浏览器
- 分配不同的用例给不同的浏览器,其实是分配用例给不同的进程,pytest-xdist默认分配用例的规则是在测试用例的维度,但是这种默认分配机制会打乱我们用例之间的关联,因此不建议使用默认分配方式
- 如果想提升执行效率,可以按照文件进行分配,pytest-xdist有一个参数,--dist=loadfile,如果想执行兼容性测试,那么每个浏览器都需要执行所有用例,可以用--dist=each
- 多进程并发数据冲突问题
- 数据冲突主要是使用的用户是同一个,因此我们可以给不同的进程分配不同的用户,就可以解决这个问题
if worker_id=='master': BuyerLoginActions().buyer_login(username=usernames[0],password=pwd_list[0]) else: index = int(worker_id[2:]) BuyerLoginActions().buyer_login(username=usernames[index], password=pwd_list[index])