当我们的自动化规模很大的时候,一次运行需要很多时间,这就需要有一个调度机制,最好是多个设备同时运行。在pc上还好说,可以用selenium grid, 然后用多线程跑,pytest-xdist是好用的。 但是mobile是连接多个设备的。我尝试了一下,要么多台设备同时跑一样的case, 这样可以测试兼容性。但是我们想在不同的机器同时跑不同的case. 本人尝试了多线程,理想很丰满,现实很骨感。 多线程没起到效果,一般是一台机跑,一台机等着。等第一台跑完,第二台就跑。
代码语言:javascript复制import os
import time
import threading
from globals import get_devices_list
def run_device(device):
pytest.main(['-v', 'Cases/test_lesson.py', "--alluredir", "./Reports/xml","--device={}".format(device)])
def start():
threads = []
for i in get_devices_list():
threads.append(threading.Thread(target=run_device, (i,)))
for t in threads:
time.sleep(0.3)
t.start()
for t in threads:
t.join()
这样我们在启动设备的时候,需要定义:
代码语言:javascript复制@pytest.fixture(scope="session")
def cmdopt(request):
return request.config.getoption("--cmdopt")
@pytest.fixture(scope="module")
def driver(cmdopt):
_driver = u2.connect(cmdopt)
d = Device(_driver)
d.start_app()
yield _driver
这个应该是多线程阻塞了。
有没有别的办法呢? 上次我们谈到调度问题,具体怎么做呢? 我用我记得不是很清楚的pipline知识,写了一个jenkinsfile
代码语言:javascript复制
pipeline {
agent none
parameters {
string(name: 'HW', defaultValue: '10.128.37.216', description: 'Who should I say hello to?')
string(name: 'HONNOR', defaultValue: '10.128.36.107', description: 'Who should I say hello to?')
}
stages('run ui automation'){
stage('go to destination') {
steps {
bat "cd C:/work/code/regression"
}
}
stage('run cases') {
parallel {
stage('Run in huawei') {
steps {
echo "device is huawei"
echo "device id is: ${params.HW}"
bat "python -m pytest -s -v Cases/test_lesson.py --alluredir ./Reports/xml --cmdopt=${params.HW}"
}
}
stage('Run in honnor') {
steps {
echo "device is honnor"
echo "device id is ${params.HONNOR}"
bat "python -m pytest -s -v Cases/test_login.py --alluredir ./Reports/xml --cmdopt=${params.HONNOR}"
}
}
}
}
}
post('report') {
always{
script{// 集成allure,目录需要和保存的results保持一致,注意此处目录为job工作目录之后的目录,Jenkins会自动将根目录与path进行拼接
allure includeProperties: false, jdk: '', report: 'report/allure-report', results: [[path: 'report/allure-results']]
}
failure {
mail to: team@example.com, subject: 'The Pipeline failed :('
}
}
}
写完需要检查,可以用vscode装 Jenkins Pipeline Linter Connector 插件 只要代码仓库里存在声明式流水线,就可以使用这个插件去验证是否存在语法错误问题。
安装插件 在 VSCode 插件里搜索 Jenkins Pipeline Linter Connector
配置插件 打开 File -> Preferences -> Settings -> Extensions, 找到 Jenkins Pipeline Linter Connector 运行插件 右键 -> Command Palette -> Validate Jenkinsfile 或 执行快捷键 Shift Alt V 这样就可以检查jenkinsfile是否正确了。 当不会写某些片段代码时,可以用Jenkins pipeline片段生成器
拉取代码举例,如下图配置好,从Git上拉代码可以将scm处选择为git
配置好之后点击【生成流水线代码】即可
allure集成举例,配置好之后点击【生成流水线代码】即可生成代码
然后跑起来,结果出了个错:Errors encountered validating Jenkinsfile: Unsupported class file major version 58 看起来是jdk版本过高,我醉了。
看来得用另外一种方法了,线程池。
代码语言:javascript复制def run_cases(device,case):
"""
参数:device为设备启动参数。在pytest.main当中,传递给--cmdopt选项。
"""
print("device is --cmdopt={}".format(device))
pytest.main(["-s", "-v","Cases/{}".format(case),"--alluredir", "./Reports/xml","--cmdopt={}".format(device)])
def parall():
# 从设备池当中,获取当前连接的设备。若设备池为空,则无设备连接。
devices = get_devices_list()
if devices:
# 创建线程池
T = ThreadPoolExecutor()
# 若设备池不为空,执行app自动化测试。
cases=["test_lesson.py","test_login.py"]
obj_list = []
for device,case in zip(devices,cases):
task = T.submit(run_cases, device,case)
obj_list.append(task)
time.sleep(1)
结果流畅得跑起来了,结果可以合并在一起,爽得很。 关于线程池,下回再讲。