搭建框架的几点思考:
- 需要框架实现什么功能
- 前期需要做数据与业务分离,方便维护
- 测试用例集管理要方便,便于异常时重新Run单条用例
- 用例设计需要尽可能简单,多提供公共方法
- 目前设计框架如下图:
- CommonLibrary 用于存放公共库
- TestCasesRepository 用于存放测试用例
- TestData 用于存放与测试用例有关的测试数据文档
- TestRun_xxx 是测试过程中生成的测试结果,内含测试报告和日志
- AutoRunTest.py 用于从用例列表中读取需要执行的测试用例文件,及测试结束后测试报告的发送
- testcases.txt 用于存放用例表
2. 其中公共库中大致有Appium的操作、Excel档的操作、手机信息的配置、测试用例信息的收集、测试结果文件夹的生产 、测试报告的写入、邮件发送等公共方法
目录如下:
如Appiumserver大致如下设计:
#! /usr/bin/env python#coding=utf-8import os,timedef start_appiumServer(port11,port12,deviceuuid): os.system("cd C:\\Program Files (x86)\\Appium\\ && start node node_modules\\appium\\lib\\server\\main.js --address 127.0.0.1 --port "+port11+ " -bp "+port12+" -U "+deviceuuid) time.sleep(2)def kill_appiumServer(port13): # 查找对应端口的pid cmd_find = 'netstat -aon | findstr %s' % port13 print(cmd_find) result = os.popen(cmd_find) text = result.read() pid = text[-5:-1] # 执行被占用端口的pid cmd_kill = 'taskkill -f -pid %s' % pid print(cmd_kill) os.popen(cmd_kill)if __name__ == '__main__': #start_appiumServer('4729','4728','BIBI5LEU6PRCDIIV') #start_appiumServer('4727','4724','75a2daf1') #time.sleep(10) kill_appiumServer(4729) kill_appiumServer(4727)
EmailUtils结构如下:
#! /usr/bin/env python#coding=utf-8import smtplibfrom os.path import basenamefrom email.mime.application import MIMEApplicationfrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextfrom email.utils import COMMASPACE,formatdatefrom datetime import datetimeimport ResultFolderfrom email.header import Headerimport zipfile,osimport decode_pwddef send_email(send_from,send_to,subject,text,files1,files2,server="smtp.163.com"): #assert(isinstance(send_to,list),"Send To email should be a list") msg = MIMEMultipart() msg['From'] = send_from msg['To'] = send_to msg['Date'] = formatdate(localtime = True) msg['Subject'] = Header(subject, 'utf-8') my_password = "7A68656E676A696E6731313238" my_pass = decode_pwd.decode_pwd(my_password) msg.attach(MIMEText(text,'html')) with open(files1,"rb") as f: part1 = MIMEApplication(f.read()) part1["Content-Type"] = 'application/octet-stream' part1["Content-Disposition"] = 'attachment; filename="TestResult.html"' msg.attach(part1) with open(files2,"rb") as g: part2 = MIMEApplication(g.read()) part2["Content-Type"] = 'application/octet-stream' part2["Content-Disposition"] = 'attachment; filename="Test.log"' msg.attach(part2) smtp = smtplib.SMTP_SSL(server,465) smtp.login(send_from,my_pass) smtp.sendmail(send_from,send_to,msg.as_string()) smtp.quit()def zip_report(startdir,file_news): print startdir z = zipfile.ZipFile(file_news,'w',zipfile.ZIP_DEFLATED) for dirpath, dirnames, filenames in os.walk(startdir): fpath = dirpath.replace(startdir, '') # 这一句很重要,不replace的话,就从根目录开始复制 fpath = fpath and fpath + os.sep or '' # 这句话理解我也点郁闷,实现当前文件夹以及包含的所有文件的压缩 for filename in filenames: z.write(os.path.join(dirpath, filename), fpath + filename) print ('压缩成功') z.close()def send_report(): send_f = "xxxxx@163.com" send_t = "xxxxxx@163.com" subject = "Software test Report_"+ str(datetime.today()) files1 = ResultFolder.GetRunDirectory()+"\\TestResult.html" print "zip log is start" zipdir = ResultFolder.GetRunDirectory()+"\\" file2_news = zipdir + 'TestLog.zip' zip_report(zipdir,file2_news) files2 = ResultFolder.GetRunDirectory() + "\\TestLog.zip" with open(files1,'r') as f: text = f.read() send_email(send_f,send_t,subject,text,files1,files2)if __name__=='__main__': send_report()
其他模块就不一一列举。