【RobotFramework】使用监听器实现 UI 性能数据分析
背景
公司最近突然要求测试 web 界面和移动端用户感知相关验证,需要部分 UI 跳转场景的性能数据,由于没有其他性能测试工具的经验,且 RF 的 UI 自动化用例已覆盖了部分需要验证的场景,就想着直接借用已有的脚本,使用监听器与插件,通过实现:
- testcase 循环执行;
- 收集所有 keywords 的运行时间 来达成目的!
最终成果
安装Ext
扩展库之后,使用命令行执行 robot 命令python -m robot --prerebotmodifier Ext.CostTime --listener Ext.RunX:2 --test Run_b_s --test Run_b_o ./
其中--listener Ext.RunX:2
代表所指定的 testcase 执行 3 遍(增加 2 遍)--prerebotmodifier Ext.CostTime
在 rebot 之前使用 CostTime 类,生成我所需要的性能数据 html 报告(类似下图)
文章源自玩技e族-https://www.playezu.com/243235.html
文章源自玩技e族-https://www.playezu.com/243235.html
实现
一、TestCase 循环执行
注册监听器,监听 start_suite 接口,在 suite 执行之前,将 suite 内部的 testcase 逐个做深拷贝,并修改 testname 添加到 suite.tests 里面,执行时就会将原有的 testcase 与我添加一并执行,从而实现循环执行的效果文章源自玩技e族-https://www.playezu.com/243235.html
class RunX:
ROBOT_LISTENER_API_VERSION = 3 #监听器版本
ROBOT_LIBRARY_SCOPE = "Global" #监听器描述
def __init__(self,num=1):
self.num = num
self.ROBOT_LIBRARY_LISTENER = self #注册监听器,监听自己
def start_suite(self, suite, *_):
print("[start suite]"+ suite.name )
testTs = copy.deepcopy(suite.tests)
for testT in testTs:
for i in range(self.num):
print("copy")
testTT = copy.deepcopy(testT)
testTT.name = testTT.name + "_" + str(i+1)
suite.tests.append(testTT)
二、获取所有 keyword 的运行时间,按格式输出到 html
suite 执行完输出 log 之前的 prerebotmodifier 阶段调用 CostTime 类,遍历 output.xml 文件,获取所有 keyword 的运行时间,keyword 名称与 keyword 所属的 testname 组成 dict,记录到列表中;再根据 keyword 名称进行分组,计算平均时间,最终使用 dominate 库输出到 html 文件中。文章源自玩技e族-https://www.playezu.com/243235.html
class CostTime(ResultVisitor):
def visit_suite(self,suite):
for test in suite.tests:
for kw in test.keywords:
self.res_list.append({"tc_name":test.name,"name":kw.name,"cost":kw.elapsedtime}) # dict追加到list
kwpath = suite.name + "." + test.name
if kw.keywords:
res = self.iter_kw( kw, kwpath, test.name) and res # 遍历
self.res_list = sorted(self.res_list, key=itemgetter('name')) #排序
doc = dominate.document(title='Result Cost Times') # 处理html三方库
with doc:
with table(style=style_str).add(tbody()):
for kw_name, tc_cost_list in groupby(self.res_list, key=itemgetter('name')): # 分组
tc_cost_list = list(tc_cost_list)
avg = sum(list(map(lambda x:x["cost"], tc_cost_list)))/len(tc_cost_list) # 平均值
tc_cost_list.append({"tc_name":"AVG","cost":avg})
for tc_cots in tc_cost_list:
with tr():
th(tc_cots["tc_name"],style=style_str)
th(str(tc_cots["cost"])+"ms",style=style_str)
with open("./result_costTime.html",'w') as result_costTime: # 写入html文件
result_costTime.write(doc.render())
源码
https://gitee.com/chonger09/rf_source文章源自玩技e族-https://www.playezu.com/243235.html
注
此处只是一个小 demo,待实际使用还会做很多优化点,菜鸡一枚,折腾了好久才有点进展,就单纯发出来分享一下,大神见谅文章源自玩技e族-https://www.playezu.com/243235.html
文章源自玩技e族-https://www.playezu.com/243235.html文章源自玩技e族-https://www.playezu.com/243235.html
未知地区 2F
是的 UI 相关的性能还需要调研一下,公司之前没有这一块技术积累 上次验证还是掐的秒表
未知地区 1F
应该不算性能数据,只是一个耗时,而且准确性有待商榷