编写一个错误自动记录log的装饰器
只要在需要记录log的方法前加上:@errorlog 就可以了
def errorlog(func): logger = logging.getLogger() def wrapper(self, *args, **kwargs): try: return func(self, *args, **kwargs) # 执行传入的fn参数 except Exception as e: logger.error(msg=e, exc_info=True) return wrapper
版本1.1.4源码
各个版本功能介绍:
操作步骤 双击devicesConnect.exe即可运行 使用此工具注意事项及操作步骤 1.电脑端cmd可执行adb命令,设备已预置安装所需apk文件。 2.myExcel文件夹中存放所需测试的Excel,文件名固定为Test.xlsx,并只能放一个。 3.Excel表中Select列不能为空,只能为0或1。 4.myExcel和resultExcel两个文件夹名字不能更改。 5.右布局的国家语言需要手动在excel表格中编辑格式。 语言切换工具1.1.4版本功能介绍: 1.优化语言切换判断 2.优化不存在语言判断 语言切换工具1.1.3版本功能介绍: 1.更新日志保存方式,修复控制台显示'GBK'编码报错问题。 2.优化运行出错的容错率,当前语言出错会跳过并保存日志。 3.控制台显示为空或乱码问题,请看pdf文档进行设置。 语言切换工具1.1.2版本功能介绍: 1.新增日志文件,可在resultExcel文件夹中查看 2.新增配置文件,在setting文件中,可更改对应元素位置(详细请看setting中的readme.txt) 3.新增语言判断,若当前语言不存在设备,则会跳过 4.新增warning信息对比,当设备无更新提示时会记录当前设备版本信息 语言切换工具1.1.1版本功能介绍: 1.可显示当前语言切换进度。 2.设备中无目标语言会跳过执行。 3.resultExcel文件夹中会生成测试结果,文件夹以当前时间命名。 4.生成的excel文件中会有对应截图超链接,需要点击两次才能跳转。
目录结构
readExcelFile.py
import xlrd class RWExcel: def __init__(self,filename): # todo 打开excle self.xl = xlrd.open_workbook('{}'.format(filename)) # todo 通过索引获取工作表 self.table = self.xl.sheet_by_index(0) # print("工作表的名字为:{}".format(self.table.name)) # 获取一共多少行 self.rows = self.table.nrows # 获取一共有多少列 self.cols = self.table.ncols # print("当前表一共有"+str(self.rows) +"行,"+ str(self.cols) + "列") # for i in range(rows): # print(table.cell(i,0)) #打印第一列 def getSelect(self): """ :return: 获取表中select为1的行数(下标从0开始) """ #读取表格第一列除去第一行的值 self.fristcol = self.table.col_values(0) fristcol_list = [] fristcol_list.append(self.table.cell(0,0).value) #把第一行第一列的值加进去 for i in range(1,len(self.fristcol)) : # 把除去第一行的第一列的0和1强转为int类型的数值,并且加入到列表里面(第一行的值最后也在,目的是为了后面通过下标找对应的行) fristcol_list.append(int(self.fristcol[i])) #print("当前表第一列的值为:{}".format(fristcol_list)) #获取fristcol_list中为1的下标,同时用一个列表存储这些下标 indexlist = [] for i in range(len(fristcol_list)) : if fristcol_list[i] == 1 : #如果为1,那就是需要运行这一行的代码,此时获取下标,就相当于是获取第几行 indexlist.append(i) # i就是下标 #print("当前表中select是1的行数为:{}".format(indexlist)) return indexlist def selectLanguage(self): """ :return: 获取表格中select为1所对应的语言列表 """ indexlist = self.getSelect() #获取select为1的列 #print("第二个方法里面的Select为1的行数{}".format(indexlist)) #print("---------------------------------") languagelist = [] for i in indexlist: #获取对应select为1的平台切换语言列表(第4列) language = self.table.cell(i,3).value languagelist.append(language) #获取select为1对应的平板切换语言 print("当前表中待切换语言:\n {}".format(languagelist)) print("\n") return languagelist def list_dic(self): ''' two lists merge a dict,a list as key,other list as value 把select为1的行数作为键,把要切换的语言作为值 :return:dict ''' list1 = self.getSelect() list2 = self.selectLanguage() #把两个列表合并为一个字典,一个作为key,一个作为value dic = dict(map(lambda x, y: [x, y], list1, list2)) return dic def differ(self,index): i = self.table.cell(index,2).value j = self.table.cell(index,4).value if i == j : print("匹配结果:一样") #print(i) #print("--------------------------------------") #print(j) return "PASS" if i != j : print("匹配结果:不一样") return "FAILED"
read SeriaNumber.py
import os class adbDevices(): def __init__(self): pass def readSN(self): ''' :return:获取设备的sn号 ''' text = os.popen("adb devices | findstr /v List").read() Sn = text.split('d')[0].split()[0] return Sn
writeExcel.py
from openpyxl import load_workbook from .readExcelFile import RWExcel #写入已存在的xlsx文件 class Write_excel(object): '''修改excel数据''' def __init__(self,filename,index,msg): """ :param filename: 测试的文件名 :param index: 对应要写入的行数的下标 :param msg: 需要写入的内容 """ self.filename = filename self.index = index self.msg = msg def write(self): #写入已存在的xlsx文件 wb = load_workbook(self.filename)#生成一个已存在的wookbook对象 wb1 = wb.active#激活sheet wb1.cell(self.index+1,5,self.msg)#往sheet中的第二行第五列写入msg的数据,注意这里的下标是从1开始 wb.save(self.filename) # 保存 def write_result(self): result = RWExcel(self.filename).differ(self.index) # 写入已存在的xlsx文件 wb = load_workbook(self.filename) # 生成一个已存在的wookbook对象 wb1 = wb.active # 激活sheet wb1.cell(self.index + 1, 6, result) # 把对比的结果写入到表格中 wb.save(self.filename) # 保存 return result #图片超链接 def write_hyperlink(self,path): result = "file:\\\\\{}".format(path) wb = load_workbook(self.filename) # 生成一个已存在的wookbook对象 wb1 = wb.active # 激活sheet wb1.cell(self.index + 1, 7, result) # 把截图的超链接写入到表格中 wb.save(self.filename) # 保存 return result def saveExcel(self): pass
deviceConnect.py (主函数)
# coding=utf-8 import time import datetime from language_draft_exe03.commonFiles.readSerialNumber import adbDevices from language_draft_exe03.commonFiles.readExcelFile import RWExcel from language_draft_exe03.commonFiles.writeExcel import Write_excel import uiautomator2 as u2 import os import logging import configparser def errorlog(func): logger = logging.getLogger() def wrapper(self, *args, **kwargs): try: return func(self, *args, **kwargs) # 执行传入的fn参数 except Exception as e: logger.error(msg=e, exc_info=True) return wrapper class readWarningTest(): def __init__(self): pass def copyExcel(self): """ :return:返回复制后的excel的绝对路径 """ nowTime = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S') self.makeFolder = os.popen(r"cd resultExcel && mkdir {} && cd {} && chdir".format(nowTime,nowTime)).read() self.makeFolderPath = self.makeFolder.strip() #这个打印的鬼地址末尾有个\n , 这里把他去掉 #print(self.makeFolderPath) self.rootdir = os.popen("copy .\myExcel\ {}\ /Y".format(self.makeFolderPath)) self.resultExcelPath = "{}\Test.xlsx".format(self.makeFolderPath) print("--------------------表格备份完成----------------") #print(self.resultExcelPath,"-------------------------") return self.resultExcelPath def savelog(self): path = "{}\main.log".format(self.makeFolderPath) logging.basicConfig(level=logging.DEBUG, # 控制台打印的日志级别 filename=path, filemode='w', ##模式,有w和a,w就是写模式,每次都会重新写日志,覆盖之前的日志 # a是追加模式,默认如果不写的话,就是追加模式 format= '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s' # 日志格式 ) def readConfig(self): self.cf = configparser.ConfigParser() self.cf.read("./setting/config.ini",encoding="utf-8-sig") # 读取配置文件 def getLanguageindex(self): self.readConfig() languageindex = self.cf.get("language&input", "languageindex") #获取[language&input]中languageindex对应的值 return int(languageindex)-1 def getUpdateindex(self): self.readConfig() Updateindex = self.cf.get("systemUpdate", "Updateindex") # 获取[systemUpdate]中Updateindex对应的值 return int(Updateindex) def getExcelName(self): self.readConfig() excelName = self.cf.get("ExcelName",'excelName') return excelName def errorScreenshorts(self, msg, Changelanguage): self.d.screenshot("{}\{}_{}.jpg".format(self.makeFolderPath, Changelanguage, msg)) self.picturePath = "{}\{}_{}.jpg".format(self.makeFolderPath, Changelanguage, msg) @errorlog def connect(self): self.savelog() logger = logging.getLogger() # 连接手机 print("---------------正在获取设备的SN号----------------") logging.debug(msg="---------------正在获取设备的SN号----------------",exc_info=True) try: self.SN = adbDevices().readSN() # 获取涉笔的SN号 print("------------------获取成功,设备的SN号为:" + self.SN + "----------------------") except Exception as e: logger.error(e,exc_info=True) self.savelog() time.sleep(5) print("---------------------------正在连接设备---------------------") try: self.d = u2.connect(self.SN) # HA12FYBL\HA12G0GW\HA169RPZ填入设备的SN号即可 except Exception: logger.error('连接设备出错', exc_info=True) self.sizeTuple = self.d.window_size() print("--------------------设备连接成功,开始运行-----------------") self.savelog() #self.d.press('home') #print("回到主页面成功,正在把屏幕调到自然方向") #time.sleep(3) #self.d.set_orientation("n") # or "natural" #print("屏幕调整完成,正在启动应用") @errorlog def readWarning(self,Changelanguage): """ :param Changelanguage: 需要切换的语言 :return: 返回切换语言之后的warningtext """ self.savelog() logger = logging.getLogger() logger.debug('-------------------回到主界面成功,正在启动应用!-----------------', exc_info=True) self.d.press('home') time.sleep(3) self.d.implicitly_wait(20) #启动应用 self.d.app_start("com.android.settings") logger.debug('---------------------应用启动成功---------------------', exc_info=True) #创建session连接对象,建议与设置应用的绑定连接 s = self.d.session('com.android.settings',attach=True) time.sleep(3) #获取设备的尺寸 #print(self.d.window_size()) x = self.sizeTuple[0] y = self.sizeTuple[1] #print("屏幕的宽为:"+str(x) +",屏幕的高为:"+str(y)) #获取屏幕的宽高 #1.进入设置之后,划动屏幕找到System time.sleep(3) #print("---------------------开始滑屏--------------------") self.d.swipe(x/5 * 4,y/5 * 4,x/5*4,y/5*1,1,50) self.d.swipe(x/5 * 4,y/5 * 4,x/5*4,y/5*1,1,50) #print("---------------------滑屏结束-----------------------") self.d.implicitly_wait(5) #2.通过class和下标点击系统(开发者模式) n1 = self.d(className='android.widget.RelativeLayout').count self.d(className='android.widget.RelativeLayout')[n1 - 1].click() #self.d(className = 'android.widget.LinearLayout',index = '18').click() #3.点击语言和输入法 n2 = self.getLanguageindex() self.d(className = 'android.widget.LinearLayout',index = n2).click() time.sleep(2) #4.点击语言 self.d(className = 'android.widget.RelativeLayout',index = '1').click() time.sleep(2) #5.点击添加语言(此时页面仅可存在一个语言,其他语言需提前删除)(需判断目前显示的语言是否和要搜索的一致) self.d(resourceId = 'com.android.settings:id/add_language').click() #6.点击搜索 self.d(resourceId = 'android:id/locale_search_menu').click() self.savelog() #7.输入需要更换的语言(此时要注意一个语言下面还有分支的情况) # Changelanguage = 'Čeština' #Suomi Akan time.sleep(3) # 7.1 单语言切换 self.Changelanguage = Changelanguage if "/" not in self.Changelanguage: self.d(resourceId='android:id/search_src_text').send_keys(self.Changelanguage) time.sleep(2) clickelecment = self.d(resourceId='android:id/locale').exists if clickelecment: self.d.implicitly_wait(5) # 8.1选择更换的语言,text要是选择的语言,有的语言会有推荐语言列表 self.d(resourceId='android:id/locale').click() time.sleep(5) # 如果当前语言为多语言,而表格中输入的是单语言,会进行判断 judgeSearch = self.d(resourceId='com.android.settings:id/add_language').exists logger.debug('------------------判断了' + str(judgeSearch) + '----------------', exc_info=True) # print("判断了",judgeSearch) if judgeSearch: pass elif str(judgeSearch) == "False": logger.debug('------------------切换语言失败,请检查当前语言在表格是否漏填次语言------------------', exc_info=True) print("切换语言失败,请检查当前语言在表格是漏填次语言") self.errorScreenshorts("切换失败", self.Changelanguage) self.d.press("home") return "faile" else: logger.debug('-----------------当前设备不存在此语言或当前设备语言为此语言------------------', exc_info=True) print("当前设备不存在此语言或当前设备语言为此语言") self.errorScreenshorts("切换失败", self.Changelanguage) time.sleep(2) self.d.press("home") return "fail" self.savelog() time.sleep(1) # 7.2 多语言切换(英语有很多页,需要滑动的,分开操作) if "/" in self.Changelanguage: self.Changelanguage = self.Changelanguage.replace("/", "-") # print("含有/符号的value:{}".format(self.Changelanguage)) # 把含有/的value打印出来 multilingual = self.Changelanguage.split("-") # 分割好的语言放在这个里面 # print("--------------------------------") # print("分割的", multilingual) hostLanguage = multilingual[0] # 获取多语言的主语言 secondLanguage = multilingual[1] # 获取多语言的子语言 # print("secondLanguage:{}".format(secondLanguage)) time.sleep(3) if multilingual[0] == "English": self.d(resourceId='android:id/search_src_text').send_keys(hostLanguage) self.d.implicitly_wait(5) # 8.1点击主语言进入次语言的选择界面 self.d(resourceId='android:id/locale', text=hostLanguage).click() time.sleep(2) # 寻找子语言,如果子语言不存在,则滚动屏幕,直到找到子语言,找到子语言则跳出循环,进行后面的操作 flag = True while flag: # 判断元素是否存在 time.sleep(5) judgeElement = self.d(resourceId='android:id/locale', text=secondLanguage).exists if judgeElement: logger.debug('---------------次语言查找成功----------------', exc_info=True) # print("---------------次语言查找成功----------------") self.d(resourceId='android:id/locale', text=secondLanguage).click() flag = False else: x = self.sizeTuple[0] # 获取屏幕的宽 y = self.sizeTuple[1] # 获取屏幕的高 logger.debug('--------------滑屏寻找元素--------------', exc_info=True) # print("--------------滑屏寻找元素--------------") # 1.进入设置之后,划动屏幕找到System self.d.swipe(x / 5 * 4, y / 5 * 4, x / 5 * 4, y / 5 * 3, 1, 50) self.d.swipe(x / 5 * 4, y / 5 * 4, x / 5 * 4, y / 5 * 3, 1, 50) else: # 不是英语的其他多语言 self.d(resourceId='android:id/search_src_text').send_keys(hostLanguage) # print("hostLanguage:{}".format(hostLanguage)) self.d.implicitly_wait(5) # 8.1点击主语言进入次语言的选择界面 hostLanguageElement = self.d(resourceId='android:id/locale', text=hostLanguage) judgelement = hostLanguageElement.exists if judgelement: hostLanguageElement.click() time.sleep(2) secondLangeageElement = self.d(resourceId='android:id/locale', text=secondLanguage) judgeSecondLangeage = secondLangeageElement.exists if judgeSecondLangeage: secondLangeageElement.click() else: logger.debug('-----------------当前语言不存在该次语言,或当前语言为此语言------------------', exc_info=True) print("当前语言不存在该次语言,或当前语言为此语言") self.errorScreenshorts("切换语言失败", self.Changelanguage) time.sleep(2) self.d.press("home") return "fail" else: logger.debug('-----------------当前设备不存在此语言或当前设备语言为此语言------------------', exc_info=True) print("当前设备不存在此语言或当前设备语言为此语言") self.errorScreenshorts("切换语言失败", self.Changelanguage) time.sleep(2) self.d.press("home") return "fail" #print("准备点击小点") #9.选择右上角的三个小点,remove self.d(className = 'android.widget.ImageButton',index='1').click() #print("点好了") #10.点击移除(把选择之前的语言移除掉) self.d(resourceId = 'android:id/content').click() time.sleep(3) #11.勾选之前的语言(也就是第一个),这样把第一个删除之后,现在的语言就是需要更换的语言 self.d(className = 'android.widget.RelativeLayout',index = '0').click() #点击第一个语言 self.d(className = 'android.widget.TextView',index = '0').click() #点击删除 #12.由于点击第一个删除会触发系统提示弹窗,则勾选ok就好 self.d(resourceId = 'android:id/button1',index = '1').click() time.sleep(1) self.d.press("back") #返回到语言和输入法界面 time.sleep(1) self.d.press("back") #返回到系统界面(开始进入系统更新对比) logger.debug('-------------------------开始进入系统更新对比------------------', exc_info=True) #print("-------------------------开始进入系统更新对比------------------") #13.进入系统更新界面 n3 = self.d(className='android.widget.RelativeLayout').count n4 = self.getUpdateindex() self.d(className='android.widget.RelativeLayout')[n3 - n4].click() #self.d(className = 'android.widget.LinearLayout',index = '8').click() self.savelog() #14.获取提示信息,先判断提示信息在不在,不在则返回该设备无更新提示信息 judgemsg = self.d(resourceId = 'com.lenovo.ota:id/text_new_version_content').exists if judgemsg: WarningText = self.d(resourceId = 'com.lenovo.ota:id/text_new_version_content').get_text(timeout=5) # print(WaringText) return WarningText else: print("当前设备无更新提示信息...") text1 = self.d(resourceId = 'com.lenovo.ota:id/current_version').get_text(timeout=2) text2 = self.d(resourceId = 'com.lenovo.ota:id/current_version_content').get_text(timeout=2) WarningText = '{}\n{}'.format(text1,text2) return WarningText # 15.把获取到的信息写入到表格中,使用获取到的信息和表格里面的信息进行对比 @errorlog def judgeResult(self): self.savelog() logger = logging.getLogger() #获取select为1的行数和语言的键值对 eg.{3: 'Latviešu', 4: '日本語'} languageList = RWExcel(self.resultExcelPath).list_dic() #print(languageList) languageTotal = len(languageList) count = 0 for key, value in languageList.items(): #print("index:{},value:{}".format(key, value)) # key作为第几行直接输入 #print("---------------------开始切换语言-------------") count += 1 percent = format(count/languageTotal, '.1%') #value = str(value) logger.debug("-------------------------正在切换语言:{},请等待-------------------".format(value), exc_info=True) print("-------正在切换语言:{},请等待......".format(value)) msg = Run.readWarning(value) #print(msg) logger.debug('-----------------------开始把warning信息写入到对应表格中------------------', exc_info=True) #print("-------------------开始把warning信息写入到对应表格中-------------------") write = Write_excel(r'{}'.format(self.resultExcelPath), key, msg) #把获取到的warning信息写入进入表格 write.write() logger.debug('---------------------Warning信息写入成功------------------', exc_info=True) #print("-------------------Warning信息写入成功--------------------------") logger.debug('---------------------开始对比系统提示与标准描述模板是否一致--------------', exc_info=True) #print("----------------------开始对比系统提示与标准描述模板是否一致----------------") logger.debug('----------------开始把测试结果写入到对应表格中---------------------', exc_info=True) #print("-------------------开始把测试结果写入到对应表格中-------------------") #把对比之后的测试结果写入到表格 result = write.write_result() logger.debug('-----------------------当前切换语言测试结果写入成功-----------------', exc_info=True) #print("-------------------当前切换语言测试结果写入成功--------------------------") logger.debug('-------------------------截图保存--------------------', exc_info=True) #print("-------------------截图保存--------------------------") # 16.获取到信息之后截屏,截图该屏幕并保存到同目录的screen文件中,图片名称为时间+语言 # nowTime = datetime.datetime.now().strftime('%m-%d-%H-%M-%S') self.d.screenshot("{}\第{}行_{}_{}.jpg".format(self.makeFolderPath, key + 1, self.Changelanguage,result)) picturePath = "{}\第{}行_{}_{}.jpg".format(self.makeFolderPath, key + 1, self.Changelanguage, result) #print(picturePath) write.write_hyperlink(picturePath) logger.debug('------------------------当前语言切换结束------------------', exc_info=True) #print("-------------------当前语言切换结束--------------------------") print("------------------- 当前进度:{}/{},完成率:{} ----------------------".format(count, languageTotal, percent)) print("\n") time.sleep(3) self.d.press("home") self.savelog() time.sleep(3) if count == languageTotal: print("-----------------已完成100%,所有语言切换完毕-----------------------") input("请点击回车按键关闭当前窗口:") if __name__ == '__main__': Run = readWarningTest() Run.copyExcel() Run.connect() Run.judgeResult()
附:小知识
[ python]获取目录下的最新文件夹/文件
def new_report(test_report): lists = os.listdir(test_report) #列出目录的下所有文件和文件夹保存到lists print(list) lists.sort(key=lambda fn:os.path.getmtime(test_report + "\\" + fn)) #按时间排序 file_new = os.path.join(test_report,lists[-1]) #获取最新的文件保存到file_new print(file_new) return file_new if __name__=="__main__": test_report="path" #目录地址 new_report(test_report)