1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 20.UI自动化测试框架搭建-标记性能较差用例

20.UI自动化测试框架搭建-标记性能较差用例

时间:2019-11-21 08:46:03

相关推荐

20.UI自动化测试框架搭建-标记性能较差用例

在拿到性能数据后需要将数据利用起来,下面对性能数据进行分析

实现:如果性能达到设定的阈值,那么这段时间执行的用例就是性能较差的用例

确定阈值

首先确定一个阈值来当做性能的告警值,暂定为以下算法

#threshold阈值#average平均值#max最大值threshold=average+(max-average)*0.8

计算各项值

在上一章已经拿到了性能数据,然后把他们插入到数据库中

由于平台是Java的所以用Java编写

构造一个HashMap来存放全部的数据

Map<String,Map<String,List<Double>>>perfSummaryData=newHashMap<>();

最终返回的数据类型为:

{"cpu":{"system":[363,25,121.43243243243244,314.6864864864865],"idle":[761,4,537.3716216216217,716.2743243243243],"pic_cpu":[373,3.2,66.42430555555556,311.6848611111111],"device_cpu_rate":[904,36,245.6418918918919,772.3283783783784],"user":[652,11,124.20945945945945,546.4418918918919]},"mem":{"free_ram":[2707.73,1720.11,2044.2376923076922,2575.0315384615387],"pid_pss":[452.18,231.72,313.105,424.365],"total_ram":[5478.93,5478.93,5478.929999999999,5478.93]},"other":null,"power":{"current":[0,0,0,0],"tempreture":[36.8,29.9,33.69638554216868,36.17927710843373],"voltage":[4.34,4.13,4.284096385542169,4.328819277108433]},"pss":{"pssList":[],"java_heap":[],"pss_system":[],"native_heap":[]},"thread":{"threadList":[272,3,191.46308724832215,255.89261744966444]},"traffic":{"device_transport":[6283.15,433.69,3777.436774193548,5782.00735483871],"device_receive":[167860.62,11597.64,106851.58806451612,155658.81361290324],"device_total":[174143.77,12031.33,110629.02451612902,161440.8209032258],"pid_tx":[6283.15,474.8,3779.061612903226,5782.332322580645],"pid_total":[174143.71,13349.69,110675.72096774195,161450.11219354838],"pid_rx":[167860.55,12874.89,106896.65838709677,155667.77167741934]},"version":"微医用户版4.6.5-内部版本号:268-灰度-待发布-创建时间:-06-2321:18:10-最近修改时间:-06-2321:18:10"}

依次解析每个版本每次执行的性能数据然后根据性能类型放到对应的List中

然后计算一下最大、最小、平均、阈值

floats.add(floats1.stream().mapToDouble(e->e).filter(e->e>0.0).max().orElse(0.0));floats.add(floats1.stream().mapToDouble(e->e).filter(e->e>0.0).min().orElse(0.0));floats.add(floats1.stream().mapToDouble(e->e).filter(e->e>0.0).average().orElse(0.0));floats.add(floats.get(2)+0.8*(floats.get(0)-floats.get(2)));//阈值

完整代码

@OverridepublicList<UiPerfSummaryDo>getPerfDataSummary(UiPerfPageQuerypageQuery){List<UiPerfDo>perfData=uiReportMapper.getPerfData(pageQuery);Map<String,Map<String,List<Double>>>perfSummaryData=newHashMap<>();String[]cpuKeys={"device_cpu_rate","user","system","idle","pic_cpu"};String[]memKeys={"total_ram","free_ram","pid_pss"};String[]powerKeys={"voltage","tempreture","current"};String[]threadKeys={"threadList"};String[]pssKeys={"pssList","java_heap","native_heap","pss_system"};String[]trafficKeys={"device_total","device_receive","device_transport","pid_rx","pid_tx","pid_total"};String[][]allKeys={cpuKeys,memKeys,powerKeys,threadKeys,pssKeys,trafficKeys};perfData.forEach(item->{Stringversion=item.getVersion();if(!perfSummaryData.containsKey(version)){HashMap<String,List<Double>>perfVersion=newHashMap<>();for(String[]keys:allKeys){for(Stringkey:keys){perfVersion.put(key,newArrayList<>());}}perfSummaryData.put(version,perfVersion);}Map<String,List<Double>>stringListMap=perfSummaryData.get(version);List<String>cpus=JSONArray.parseArray(item.getCpu(),String.class);List<String>mems=JSONArray.parseArray(item.getMem(),String.class);List<String>powers=JSONArray.parseArray(item.getPower(),String.class);List<String>threads=JSONArray.parseArray(item.getThread(),String.class);List<String>psss=JSONArray.parseArray(item.getPss(),String.class);List<String>traffics=JSONArray.parseArray(item.getTraffic(),String.class);cpus.forEach(cpu->{List<String>oneCpuInfo=JSONArray.parseArray(cpu,String.class);if(!oneCpuInfo.isEmpty()){for(inti=1;i<6;i++){List<Double>datalist=stringListMap.get(cpuKeys[i-1]);datalist.add(Double.parseDouble(oneCpuInfo.get(i)));}}});mems.forEach(mem->{List<String>oneMemInfo=JSONArray.parseArray(mem,String.class);if(!oneMemInfo.isEmpty()){for(inti=1;i<4;i++){List<Double>datalist=stringListMap.get(memKeys[i-1]);datalist.add(Double.parseDouble(oneMemInfo.get(i)));}}});powers.forEach(power->{List<String>onePowerInfo=JSONArray.parseArray(power,String.class);if(!onePowerInfo.isEmpty()){for(inti=1;i<4;i++){List<Double>datalist=stringListMap.get(powerKeys[i-1]);datalist.add(Double.parseDouble(onePowerInfo.get(i)));}}});threads.forEach(thread->{List<String>oneThreadInfo=JSONArray.parseArray(thread,String.class);if(!oneThreadInfo.isEmpty()){for(inti=1;i<2;i++){List<Double>datalist=stringListMap.get(threadKeys[i-1]);datalist.add(Double.parseDouble(oneThreadInfo.get(i)));}}});psss.forEach(pss->{List<String>onePssInfo=JSONArray.parseArray(pss,String.class);if(!onePssInfo.isEmpty()){for(inti=1;i<5;i++){List<Double>datalist=stringListMap.get(pssKeys[i-1]);datalist.add(Double.parseDouble(onePssInfo.get(i)));}}});traffics.forEach(traffic->{List<String>oneTrafficInfo=JSONArray.parseArray(traffic,String.class);if(!oneTrafficInfo.isEmpty()){for(inti=1;i<7;i++){List<Double>datalist=stringListMap.get(trafficKeys[i-1]);datalist.add(Double.parseDouble(oneTrafficInfo.get(i)));}}});});List<UiPerfSummaryDo>uiPerfSummaryDos=newArrayList<>();List<Double>floats;for(Stringkey:perfSummaryData.keySet()){UiPerfSummaryDouiPerfSummaryDo=newUiPerfSummaryDo();Map<String,List<Double>>stringListMap=perfSummaryData.get(key);uiPerfSummaryDo.setVersion(key);for(String[]all_key:allKeys){HashMap<String,List<Double>>dataDict=newHashMap<>();for(Stringkey1:all_key){floats=newArrayList<>();List<Double>floats1=stringListMap.get(key1);if(!floats1.isEmpty()){floats.add(floats1.stream().mapToDouble(e->e).filter(e->e>0.0).max().orElse(0.0));floats.add(floats1.stream().mapToDouble(e->e).filter(e->e>0.0).min().orElse(0.0));floats.add(floats1.stream().mapToDouble(e->e).filter(e->e>0.0).average().orElse(0.0));floats.add(floats.get(2)+0.8*(floats.get(0)-floats.get(2)));//阈值}dataDict.put(key1,floats);}if(Arrays.equals(all_key,cpuKeys)){uiPerfSummaryDo.setCpu(dataDict);}if(Arrays.equals(all_key,memKeys)){uiPerfSummaryDo.setMem(dataDict);}if(Arrays.equals(all_key,powerKeys)){uiPerfSummaryDo.setPower(dataDict);}if(Arrays.equals(all_key,threadKeys)){uiPerfSummaryDo.setThread(dataDict);}if(Arrays.equals(all_key,pssKeys)){uiPerfSummaryDo.setPss(dataDict);}if(Arrays.equals(all_key,trafficKeys)){uiPerfSummaryDo.setTraffic(dataDict);}}uiPerfSummaryDos.add(uiPerfSummaryDo);}returnuiPerfSummaryDos;}

解析Allure报告

拿到一个用例的开始时间和结束时间,方便确定用例执行的时间范围

在13.UI自动化测试框架搭建-处理Allure报告数据中有提到如何拿到allure的内容

data={"fullName":full_name,"status":json_data.get("status"),"labels":labels,"start":json_data.get("start",0),"stop":json_data.get("stop",0),"duration":json_data.get("stop",0)-json_data.get("start",0),"parameters":parameters,"statusDetails":statusDetails1,"kano_url":",".join(kano_url),"steps":";".join(steps),"desc":";"}

添加了

"start":json_data.get("start",0)"stop":json_data.get("stop",0)"desc":";"

现在将用例执行的情况写入到一份csv文件中,方便与其他的性能数据进行比对

#拼接csv文件路径casesfile=os.path.join(PERF_PATH,'cases.csv')#csv文件头部title=["datetime","flag"]+list(allure_results[0].keys())withopen(casesfile,"a+",encoding="utf-8")asf:#写入头部csv.writer(f,lineterminator='\n').writerow(title)foriinallure_results:allure_data1=[timeoperator.get_localtime(i['start'],"%Y-%m-%d%H-%M-%S"),True]+list(i.values())allure_data2=[timeoperator.get_localtime(i['stop'],"%Y-%m-%d%H-%M-%S"),False]+list(i.values())csv.writer(f,lineterminator='\n').writerow(allure_data1)csv.writer(f,lineterminator='\n').writerow(allure_data2)

使得datetime等于start和stop,写入两遍,再使用flag来标记方便后面去除掉

这样就得到一份按照时间排序的用例执行结果了

datetime,flag,fullName,status,labels,start,stop,duration,parameters,statusDetails,kano_url,steps,desc-08-0114-04-44,True,src.cases_android.wy.test_health.TestMedicationReminder#test_close_medication_reminder,passed,微医APP_健康_用药提醒-关闭用药提醒(@钟鑫),1659333884508,1659333917256,32748,,"{'message':'','trace':''}",,1-查看提醒状态;1.1-查看「用药提醒_已开启提醒」是否存在;2-关闭用药提醒;2.1-点击「用药提醒_提醒滑块1」;3-点击确认;3.1-点击「通用_确认关闭」;4-查看提醒状态;4.1-查看「用药提醒_已关闭提醒」是否存在;4.2-查看「用药提醒_已关闭提醒1」是否存在;5-打开用药提醒;5.1-点击「用药提醒_提醒滑块2」;5.2-点击「用药提醒_已关闭提醒1」;6-查看提醒状态;6.1-查看「用药提醒_已开启提醒」是否存在,;-08-0114-05-17,False,src.cases_android.wy.test_health.TestMedicationReminder#test_close_medication_reminder,passed,微医APP_健康_用药提醒-关闭用药提醒(@钟鑫),1659333884508,1659333917256,32748,,"{'message':'','trace':''}",,1-查看提醒状态;1.1-查看「用药提醒_已开启提醒」是否存在;2-关闭用药提醒;2.1-点击「用药提醒_提醒滑块1」;3-点击确认;3.1-点击「通用_确认关闭」;4-查看提醒状态;4.1-查看「用药提醒_已关闭提醒」是否存在;4.2-查看「用药提醒_已关闭提醒1」是否存在;5-打开用药提醒;5.1-点击「用药提醒_提醒滑块2」;5.2-点击「用药提醒_已关闭提醒1」;6-查看提醒状态;6.1-查看「用药提醒_已开启提醒」是否存在,;-08-0113-24-32,True,src.cases_android.wy.test_me.TestSetting#test_entrance_text,passed,微医APP_个人中心_设置-子项入口文案检查(@钟鑫),1659331472953,1659331473076,123,'settings_message',"{'message':'','trace':''}",,1-查看是否存在我_设置-消息通知;1.1-查看「我_设置-消息通知」是否存在,;-08-0113-24-33,False,src.cases_android.wy.test_me.TestSetting#test_entrance_text,passed,微医APP_个人中心_设置-子项入口文案检查(@钟鑫),1659331472953,1659331473076,123,'settings_message',"{'message':'','trace':''}",,1-查看是否存在我_设置-消息通知;1.1-查看「我_设置-消息通知」是否存在,;

数据比对

读取用例执行结果

读取文件后将它的datetimes设置为datetime类型,方便后面的排序

defcases_handle(self,path=f"{PERF_PATH}/cases.csv"):df=self.read_csv(path)df['datetime']=pd.to_datetime(df['datetime'],format="%Y-%m-%d%H-%M-%S")df=df.sort_values("datetime",ascending=True)returndf

编写比较函数

defadd_desc(self,**kwargs)->[dict]:...

**kwargs动态输入键值对来进行筛选

记录原先的列

base_title=list(cases_df.columns)

先进行cpu性能数据的处理

cpu=['device_cpu_rate%','user%','system%','idle%','pid_cpu%']

遍历输入的键值对,如果输入的key值加上%在cpu这个列表里面,那就筛选出cpu性能数据中符合条件的数据

fork,vinkwargs.items():iff"{k}%"incpu:name=f"{k}%"df1=cpu_df[cpu_df[name]>v]

将两个表合并一下

cases_df=pd.concat([df1,cases_df]).sort_values("datetime",ascending=True)

拿到超过阈值的行号索引

error_index=list(cases_df[cases_df[name]>0].index)

在超过阈值索引的附近几行添加描述

foriinerror_index:cases_df.loc[i,'desc']+=f"{k}超过阈值;"try:cases_df.loc[i-1,'desc']+=f"{k}超过阈值;"exceptException:passtry:cases_df.loc[i+1,'desc']+=f"{k}超过阈值;"exceptException:pass

剔除性能数据的列

cases_df=cases_df[pd.notnull(cases_df['fullName'])]

根据flag去除重复添加的用例信息

cases_df=cases_df[cases_df['flag']==True]

根据之前保留的原始列信息将性能数据列去除

new_df=pd.DataFrame(cases_df,columns=base_title)

返回[dict]格式

returnnew_df.to_dict("records")

全部新增代码

defcases_handle(self,path=f"{PERF_PATH}/cases.csv"):df=self.read_csv(path)df['datetime']=pd.to_datetime(df['datetime'],format="%Y-%m-%d%H-%M-%S")df=df.sort_values("datetime",ascending=True)returndfdefadd_desc(self,**kwargs)->[dict]:cpu=['device_cpu_rate%','user%','system%','idle%','pid_cpu%']mem=['total_ram(MB)','free_ram(MB)','pid_pss(MB)']power=['voltage(V)','tempreture(C)','current(mA)']traffic=['device_total(KB)','device_receive(KB)','device_transport(KB)','pid_rx(KB)','pid_tx(KB)','pid_total(KB)']cpu_df=self.cpu_handle()mem_df=self.mem_handle()power_df=self.power_handle()thread_df=self.thread_num_handle()traffic_df=self.traffic_handle()cases_df=self.cases_handle()base_title=list(cases_df.columns)fork,vinkwargs.items():iff"{k}%"incpu:name=f"{k}%"df1=cpu_df[cpu_df[name]>v]iff"{k}(MB)"inmem:name=f"{k}(MB)"df1=mem_df[mem_df[name]>v]ifany([f"{k}({i})"inpowerforiin['V','C','mA']]):ifk=="voltage":name=f"{k}(V)"df1=power_df[power_df[name]>v]ifk=="tempreture":name=f"{k}(C)"df1=power_df[power_df[name]>v]ifk=="current":name=f"{k}(mA)"df1=power_df[power_df[name]>v]ifk=="threadList":name="thread_num"df1=thread_df[thread_df[name]>v]iff'{k}(KB)'intraffic:name=f'{k}(KB)'df1=traffic_df[traffic_df[name]>v]cases_df=pd.concat([df1,cases_df]).sort_values("datetime",ascending=True)error_index=list(cases_df[cases_df[name]>0].index)foriinerror_index:cases_df.loc[i,'desc']+=f"{k}超过阈值;"try:cases_df.loc[i-1,'desc']+=f"{k}超过阈值;"exceptException:passtry:cases_df.loc[i+1,'desc']+=f"{k}超过阈值;"exceptException:passcases_df=cases_df[pd.notnull(cases_df['fullName'])]cases_df=cases_df[cases_df['flag']==True]new_df=pd.DataFrame(cases_df,columns=base_title)returnnew_df.to_dict("records")

测试

cases_data=d.add_desc(device_cpu_rate=700,user=125,system=300,idle=700,pid_cpu=300,free_ram=2575,pid_pss=424,total_ram=5478,tempreture=36,voltage=4,threadList=255,device_transport=5782,device_receive=155658,device_total=161440,pid_tx=5782,pid_total=161450,pid_rx=155667,)

[...{'datetime':Timestamp('-08-0114:05:17'),'flag':True,'fullName':'src.cases_android.wy.test_health.TestMedicationReminder#test_edit_medication_reminder','status':'passed','labels':'微医APP_健康_用药提醒-修改用药提醒时间(@钟鑫)','start':1659333917269.0,'stop':1659333926307.0,'duration':9038.0,'parameters':nan,'statusDetails':"{'message':'','trace':''}",'kano_url':nan,'steps':'1-点击一条用药提醒记录;1.1-点击「用药提醒_其中一条用药提醒」;2-选择必要时用药;2.1-获取元素的坐标;2.2-点击坐标「558.0」「640.5」所在的位置;2.3-点击坐标「558.0」「640.5」所在的位置;2.4-点击坐标「558.0」「640.5」所在的位置;2.5-从元素「用药提醒_用药时间-每隔几天用药」滑动到元素「用药提醒_用药时间-每隔几小时用药」的位置;2.6-点击「通用_完成」;3-点击保存;3.1-点击「通用_保存」;4-查看提醒时间为必要时;4.1-转换参数化元素;4.2-查看「用药提醒_用药时间」是否存在','desc':';system超过阈值;device_cpu_rate超过阈值;voltage超过阈值;voltage超过阈值;voltage超过阈值;'}...]

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。