airtest+poco多脚本、多设备批处理运行测试用例自动生成测试报告_airtest测试报告

pip install selenium

pip install pynput

pip install airtest_selenium


关于这一步的安装也就是 pip install airtest\_selenium,也可以从airtest安装目录下拷贝该文件夹到python目录下


我的python目录为:G:\python3.6.5;


我的airtest安装目录为:G:\AirtestIDE\_2020-01-21\_py3\_win64\AirtestIDE\_2020-01-21\_py3\_win64,该路径下有个airtest\_selenium文件夹;


可以拷贝airtest目录下的airtest\_selenium文件夹到python目录下。


如果想用airtest编写selenium即pc自动化脚本,除了安装上面的包,因为airtest-selenium自动化因为需要打开浏览器,所以我们还需要配置谷歌浏览器路径和下载匹配的谷歌驱动文件


airtest设置谷歌启动路径:airtestIDE界面-点击选项-点击设置-点击chrome path-选择谷歌安装路径一直到chrome.exe文件


![图片](https://img-blog.csdnimg.cn/9c0b3c40fd034188a59655eb9efe07a3.png)


下载匹配的谷歌驱动文件:


可以使用该网站下载:https://npm.taobao.org/mirrors/chromedriver


下载后替换掉airtest根目录我的路径是G:\AirtestIDE\_2020-01-21\_py3\_win64\AirtestIDE\_2020-01-21\_py3\_win64下的chromedriver.exe文件即可


### 4.框架版本说明


该框架使用版本如下:



python 3.6.5

airtest 1.1.3

pocoui 1.0.79

pynput 1.6.8

airtestIDE 1.2.3


### 四:框架搭建、框架运行说明


### 1.框架搭建


该框架搭建很简单,就是一个python工程:


该工程根目录下开始时有一个result空文件夹、一个report\_tpl.html模板文件、run.py启动脚本、docs文件夹是我自己放的一些项目描述文档可有可无,.air文件是自己通过airtestIDE编写的项目的自动化脚本


![图片](https://img-blog.csdnimg.cn/1fec5a700a354a82a620324aadabbf41.png)


### 2.框架脚本文件说明



run.py #启动文件,python run.py即可
report_tpl.html #测试报告模板文件
report.html #自动生成的测试报告文件,会将汇总的执行结果的json数据即下面的summary数据格式与report_tpl.html结合,生成测试报告
result #文件夹,用于存放每个测试用例的执行json结果数据格式为下面的results数据格式
xxx.air #测试用例,所有以.air文件名称结尾的文件夹都是测试用例
xxx.air/log #每个测试用例的日志文件,以设备号区分,每个设备号下存放一份测试结果日志文件
log.html #每个测试用例在每个设备中运行的具体效果,即测试报告中点击具体测试用例右侧弹出的页面详情效果
log.txt #每个测试用例在每个设备中运行的json结果数据


### 3.框架运行编写建议


执行命令时可以用python run.py运行整个框架


但是写脚本或者调试脚本时,用airtestIDE来操作,即从airtestIDE中新建编辑.air脚本保存到该框架的根目录下,调试通过后再用run.py进行批量脚本、批量设备去执行。


这样就比较清晰


### 五:框架源码


1.run.py



1 # -- encoding=utf-8 --
2 # Run Airtest in parallel on multi-device
3 import os
4 import traceback
5 import subprocess
6 import webbrowser
7 import time
8 import json
9 import shutil
10 from airtest.core.android.adb import ADB
11 from jinja2 import Environment, FileSystemLoader
12
13
14 def run(devices, airs):
15 “”“”
16 run_all
17 18 19 “”"
20 try:
21 data_r=[]
22 global time_s
23 time_s = time.time()
24 for air in airs:
25 results = load_jdon_data(air)
26 tasks = run_on_multi_device(devices, air, results)
27 for task in tasks:
28 status = task[‘process’].wait()
29 results[‘tests’][task[‘dev’]] = run_one_report(task[‘air’], task[‘dev’])
30 results[‘tests’][task[‘dev’]][‘status’] = status
31 name = air.split(“.”)[0]
32 json.dump(results, open(get_path(“result”)+os.sep+name+‘data.json’, “w”), indent=4)
33 data_r.append(results)
34 run_summary(data_r)
35 except Exception as e:
36 traceback.print_exc()
37
38
39 def run_on_multi_device(devices, air, results):
40 “”"
41 在多台设备上运行airtest脚本
42 Run airtest on multi-device
43 “”"
44 tasks = []
45 for dev in devices:
46 log_dir = get_path(“log”,dev,air)
47 #命令行执行:airtest run openOrder.air --device Android://127.0.0.1:5037/b7f0c036 --log F:\airtest_code\good_store_project\log\openOrder
48 cmd = [
49 “airtest”,
50 “run”,
51 air,
52 “–device”,
53 “Android:///” + dev,
54 “–log”,
55 log_dir
56 ]
57 try:
58 tasks.append({
59 ‘process’: subprocess.Popen(cmd, cwd=os.getcwd()),
60 ‘dev’: dev,
61 ‘air’: air
62 })
63 except Exception as e:
64 traceback.print_exc()
65 return tasks
66
67 #点击每个用例的详情页面
68 def run_one_report(air, dev):
69 “”“”
70 生成一个脚本的测试报告
71 Build one test report for one air script
72 “”"
73 try:
74 log_dir = get_path(“log”,dev, air)
75 log = os.path.join(log_dir, ‘log.txt’)
76 if os.path.isfile(log):
77 #命令行执行:airtest report F:\airtest_code\good_store_project\openOrder.air --log_root F:\airtest_code\good_store_project\log\openOrder --outfile F:\airtest_code\good_store_project\log\openOrder\openOrder.html --lang zh
78 #如果是selenium,则最后要加上selenium插件
79 #airtest report F:\airtest_code\good_store_project\openOrder.air --log_root F:\airtest_code\good_store_project\log\openOrder --outfile F:\airtest_code\good_store_project\log\openOrder\openOrder.html --lang zh --plugins airtest_selenium.report
80 cmd = [
81 “airtest”,
82 “report”,
83 air,
84 “–log_root”,
85 log_dir,
86 “–outfile”,
87 os.path.join(log_dir, ‘log.html’),
88 “–lang”,
89 “zh”
90 ]
91 ret = subprocess.call(cmd, shell=True, cwd=os.getcwd())
92 return {
93 ‘status’: ret,
94 ‘path’: os.path.join(log_dir, ‘log.html’)
95 }
96 else:
97 print(“Report build Failed. File not found in dir %s” % log)
98 except Exception as e:
99 traceback.print_exc()
100 return {‘status’: -1, ‘device’: dev, ‘path’: ‘’}
101
102
103 def run_summary(data):
104 “”“”
105 生成汇总的测试报告
106 Build sumary test report
107 “”"
108 try:
109 for i in data:
110 c = get_json_value_by_key(i,“status”)
111
112 summary = {
113 ‘time’: “%.3f” % (time.time() - time_s),
114 ‘success’: c.count(0),
115 ‘count’: len©
116 }
117 summary[‘start_all’] = time.strftime(“%Y-%m-%d %H:%M:%S”,
118 time.localtime(time_s))
119 summary[“result”] = data
120 print(“summary++++++++++”,summary)
121
122 env = Environment(loader=FileSystemLoader(os.getcwd()),
123 trim_blocks=True)
124 html = env.get_template(‘report_tpl.html’).render(data=summary)
125 with open(“report.html”, “w”, encoding=“utf-8”) as f:
126 f.write(html)
127 webbrowser.open(“report.html”)
128 except Exception as e:
129 traceback.print_exc()
130
131
132 def load_jdon_data(air):
133 “”“”
134 加载进度
135 返回一个空的进度数据
136 “”"
137 clear_log_dir(air)
138 return {
139 ‘start’: time.time(),
140 ‘script’: air,
141 ‘tests’: {}
142
143 }
144
145 def clear_log_dir(air):
146 “”“”
147 清理log文件夹 openCard.air/log
148 Remove folder openCard.air/log
149 “”"
150 log = os.path.join(os.getcwd(), air, ‘log’)
151 if os.path.exists(log):
152 shutil.rmtree(log)
153
154 #获取key为status的值
155 def get_json_value_by_key(in_json, target_key, results=[]):
156 for key,value in in_json.items(): # 循环获取key,value
157 if key == target_key:
158 results.append(value)
159 if isinstance(value, dict):
160 get_json_value_by_key(value,target_key)
161 return results
162
163 #获取路径
164 def get_path(content,device=None,air=“openCard.air”):
165 root_path = os.getcwd()
166 path = os.getcwd()
167 if content==“result”:
168 #返回测试报告路径
169 path = os.path.join(root_path,“result”)
170 elif content == “log”:
171 log_dir = os.path.join(root_path,air, ‘log’, device.replace(“.”, "
").replace(’:', ‘_’))
172 #如果没有日志路径则创建一个
173 if not os.path.exists(log_dir):
174 os.makedirs(log_dir)
175 #返回日志路径
176 path = log_dir
177 elif content == “cases”:
178 #返回测试用例路径
179 path = os.path.join(root_path,air)
180 else:
181 #返回根目录
182 path = root_path
183 return path
184
185 #获取路径下所有air的测试用例文件
186 def get_cases(path):
187 cases=[]
188 for name in os.listdir(get_path(path)): # 遍历当前路径下的文件夹和文件名称
189 if name.endswith(“.air”):
190 cases.append(name)
191 return cases
192
193 def sort_cases(cases,loginAir,outAir):
194 #清除列表中的登录、退出登录,然后将其分别添加到列表的第一位和最后一位
195 cases.remove(loginAir)
196 cases.remove(outAir)
197 cases.insert(0, loginAir)
198 cases.insert(len(airs), outAir)
199 return cases
200
201
202 if name == ‘main’:
203
204 “”"
205 初始化数据
206 Init variables here
207 “”"
208 #获取所有已连接的设备列表
209 devices = [tmp[0] for tmp in ADB().devices()]
210 #设置指定设备执行测试用例
211 # devices = [“BTY4C16705003852”,“b7f0c036”]
212 #获取所有测试用例
213 airs = get_cases(“root”)
214 #将登录用例排在最前面执行,退出用例排在最后面执行
215 sort_airs = sort_cases(airs,“loginPro.air”,“loginOutPro.air”)
216 #获取指定用例,按顺序执行
217 # sort_airs = [“openCardPro.air”,“openOrderPro.air”,“quickMoneyPro.air”]
218 “”"
219 执行脚本
220 excute scripts
221 “”"
222 # 运行所有脚本
223 run(devices, sort_airs)


2.report\_tpl.html



1
2
3
4
5
6
7
8
9 Airtest 多设备并行测试结果汇总
10
11
210
211


212

213

214

215

汇总报告


216

217
Switch to English version

218
开始时间:{{data[‘start_all’]}},耗时 {{data[‘time’]}}

219
Started at:{{data[‘start_all’]}},cost {{data[‘time’]}} s

220

221

222
成功率: {{data[“success”]}}/{{data[“count”]}}

223
Success rate: {{data[“success”]}}/{{data[“count”]}}

224

225

226

227 {{‘%0.2f’ % (data[“success”] *100 / data[“count”])}}%
228

229

230

231

232
233 全部
234 all
235 success
236 成功
237 failed
238 失败
239
240

241

242 用例列表
243 Detail
244

245

246

247
序号

248
状态

249
用例

250
设备

251
id

252
result

253
case

254
device

255

256

257 {% set ns = namespace(found=0) %}
258 {% for dat in data[‘result’] %}
259 {% for dev, item in dat[‘tests’].items() %}
260

261 {% set ns.found = ns.found + 1 %}
262
{{ns.found}}

263
{{“成功” if item[‘status’]==0 else “失败”}}

264
{{“success” if item[‘status’]==0 else “failed”}}

265
{{dat[‘script’]}}

266
{{dev}}

267
268
点击可查看详情

269
click to see detail

270

271 {% endfor %}
272 {% endfor %}
273

274

275

276

277
278

279

280
281

282

283
284

285

286

287

288

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值