Unittest框架+ddt数据驱动+HTMLTestRunner+sendmail(自动发送测试报告)+git+Jenkins

本次写的是针对有代码基础的,没基础建议先去学基础,以下所有描述内容都是我已经在公司项目实践成功的!仅供参考

整体思路:
1、接口自动化用的是Python中unittest框架
2、所有的测试数据用例存放Excel表
3、封装一套读取和写入的Excel方法
4、重写request方法(为了从Excel读取数据后对数据作分析和判断并在测试报告生成相关信息)

5、通过HTMLTestRunner运行测试用例生成网页版报告
6、将自动化脚本放到公司git上,方便其他人员获取你的代码进行编写脚本,后面会具体讲如何获取代码和提交代码(让运维人员给你开通个git账号,自己注册登录就可以了)
7、通过Jenkins构建任务,定时自动运行git上自动化脚本,后面会具体讲如何配置Jenkins

先看看我的接口自动化整个目录结构和每个文件具体是干嘛的:

一、读取表格的代码:

1 1 import xlrd,os,copy 2 2 3 3 import sys,os 4 4 5 5 #这三行代码是解决文件路径问题 6 6 7 7 curPath = os.path.abspath(os.path.dirname(__file__)) 8 8 9 9 rootPath = os.path.split(curPath)[0] 10 10 11 11 sys.path.append(rootPath) 12 12 13 13 class ExcelUtil(): 14 14 15 15 list=[] 16 16 17 17 list1 = [] 18 18 19 19 def __init__(self,excelpath,sheetname='Sheet1'): 20 20 21 21 self.data=xlrd.open_workbook(excelpath) 22 22 23 23 self.table=self.data.sheet_by_name(sheetname) 24 24 25 25 #获取第一行作为key值 26 26 27 27 self.keys=self.table.row_values(0) 28 28 29 29 #获取总行数 30 30 31 31 self.rowNum=self.table.nrows 32 32 33 33 #获取总列数 34 34 35 35 self.colNum=self.table.ncols 36 36 37 37 38 38 39 39 #此方法有俩个用处:1、获取关闭或打开的case 2、不同模块的用例也可以通过该方法区分开来 40 40 41 41 def open_case(self): 42 42 43 43 exceldata = ExcelUtil(os.path.abspath(rootPath+'/Case/Ddt_case_api/TestCase.xlsx'), 'Sheet1') 44 44 45 45 list = [] 46 46 47 47 list1 = [] 48 48 49 49 list2=[] 50 50 51 51 for i in exceldata.dict_data(): 52 52 53 53 a = i['control_case'] # 这是在Excel加的开关case的字段 54 54 55 55 if a == '': 56 56 57 57 list.append(i) 58 58 59 59 elif a=='mobile_请先登录': 60 60 61 61 list1.append(i) 62 62 63 63 elif a=='B_请先登录': 64 64 65 65 list2.append(i) 66 66 67 67 return list,list1,list2 68 68 69 69 # print(len(list)) 70 70 71 71 def dict_data(self): 72 72 73 73 if self.rowNum<=1: 74 74 75 75 print('总行数小于1') 76 76 77 77 else: 78 78 79 79 r=[] 80 80 81 81 j=1 82 82 83 83 for i in range(self.rowNum-1): 84 84 85 85 s={} 86 86 87 87 s['rowNum']=i+2 88 88 89 89 values=self.table.row_values(j) 90 90 91 91 for x in range(self.colNum): 92 92 93 93 s[self.keys[x]]=values[x] 94 94 95 95 r.append(s) 96 96 97 97 j+=1 98 98 99 99 return r 100100 101101 #通过下面这个入口进行调试 102102 103103 if __name__=='__main__': 104104 105105 a=ExcelUtil('D:\Business_ManageMent\Case\Ddt_case_api\TestCase.xlsx') 106106 107107 b=a.open_case() 108108 109109 print(b)

二、写入表格代码:

1 1 from openpyxl import load_workbook 2 2 3 3 import openpyxl 4 4 5 5 import xlrd 6 6 7 7 8 8 9 9 def Copy_excel(exclepath1,excelpath2): 1010 1111 #把excle1数据复制到excel2 1212 1313 wb2=openpyxl.Workbook() 1414 1515 wb2.save(excelpath2) 1616 1717 wb1=load_workbook(exclepath1) 1818 1919 wb2=load_workbook(excelpath2) 2020 2121 sheets1=wb1.sheetnames 2222 2323 sheets2=wb2.sheetnames 2424 2525 sheet1=wb1[sheets1[0]] 2626 2727 sheet2=wb2[sheets2[0]] 2828 2929 maxrow=sheet1.max_row 3030 3131 maxcolum=sheet1.max_column 3232 3333 for m in range(1,maxrow+1): 3434 3535 for n in range(97,97+maxcolum): 3636 3737 n=chr(n) 3838 3939 i='%s%d'%(n,m) 4040 4141 cell1=sheet1[i].value 4242 4343 sheet2[i]=cell1 4444 4545 wb2.save(excelpath2) 4646 4747 wb1.close() 4848 4949 wb2.close() 5050 5151 class Write_excel(): 5252 5353 def __init__(self,filename): 5454 5555 self.filename=filename 5656 5757 self.wb=load_workbook(self.filename) 5858 5959 #激活sheet 6060 6161 self.ws=self.wb.active 6262 6363 def write(self,row_n,col_n,value): 6464 6565 self.ws.cell(row_n,col_n).value=value 6666 6767 self.wb.save(self.filename) 6868 6969 7070 7171 7272 7373 #通过下面入口进行调试 7474 7575 if __name__=='__main__': 7676 7777 Copy_excel('D:\Business_ManageMent\Case\Ddt_case_api\TestCase.xlsx','D:\Business_ManageMent\Case\\result.xlsx') 7878 7979 wt=Write_excel('D:\Business_ManageMent\Case\\result.xlsx') 8080 8181 wt.write(1,2,'hello')

三、重写request方法及将接口返回结果根据自己的需要写入拷贝的那张Excel表中

1 1 import json 2 2 import requests 3 3 from Tool_class.read_excel_fz import ExcelUtil 4 4 from Tool_class.writeexcel_fz import Copy_excel, Write_excel 5 5 6 6 7 7 def send_requests(s, testdata): 8 8 '''封装requests请求''' 9 9 #获取Excel标格中表头为method的数据 1010 method = testdata["method"] 1111 # 获取Excel标格中表头为url的数据 1212 url = testdata["url"] 1313 try: 1414 #eval函数可以将读取到的参数内容转化成字典格式 1515 # 获取Excel标格中表头为params的数据 1616 params = eval(testdata["params"]) 1717 except: 1818 params = None 1919 # 请求头部headers 2020 try: 2121 # 获取Excel标格中表头为headers的数据 2222 headers = eval(testdata["headers"]) 2323 print("请求头部:%s" % headers) 2424 except: 2525 headers = None 2626 2727 2828 # post请求body类型 2929 # 获取Excel标格中表头为type的数据 3030 type = testdata["type"] 3131 # 获取Excel标格中表头为id的数据 3232 test_nub = testdata['id'] 3333 print("*******正在执行用例:----- %s ----**********" % test_nub) 3434 print("请求方式:%s, 请求url:%s" % (method, url)) 3535 print("请求params:%s" % params) 3636 # post请求body内容 3737 try: 3838 # 获取Excel标格中表头为body的数据 3939 bodydata = eval(testdata["body"]) 4040 except: 4141 bodydata = {} 4242 # 判断传data数据还是json 4343 if type == "json": 4444 #json.dumps将字典数据转成json格式,因为不同的接口传递参数是不同的,有的是传data,有的传json 4545 body= json.dumps(bodydata) 4646 elif type == "data": 4747 body = bodydata 4848 else: 4949 body = bodydata 5050 5151 if type=='json': 5252 print("post请求body类型为:%s ,body内容为:%s" % (type,body)) 5353 elif method=='post': 5454 print("post请求body类型为:%s ,body内容为:%s" % (type,body)) 5555 verify = False 5656 res = {} # 接受返回数据 5757 5858 try: 5959 r = s.request(method=method, 6060 url=url, 6161 params=params, 6262 headers=headers, 6363 data=body, 6464 verify=verify 6565 ) 6666 print("页面返回信息:%s" % r.json()) 6767 res['id'] = testdata['id'] 6868 res['rowNum'] = testdata['rowNum'] 6969 res["statuscode"] = str(r.status_code) # 状态码转成str 7070 res["text"] = r.json() 7171 res["times"] = str(r.elapsed.total_seconds()) # 接口请求时间转str 7272 if res["statuscode"] != "200": 7373 res["error"] = "服务错误,接口未请求成功" 7474 res["msg"] = str(res["text"]) 7575 else: 7676 res["error"] = "" 7777 res["msg"] = "" 7878 if testdata["checkpoint"] == res["text"]['msg']: 7979 res["result"] = "pass" 8080 print("用例测试结果: %s---->%s" % (test_nub, res["result"])) 8181 else: 8282 res["result"] = "fail" 8383 return res 8484 except Exception as msg: 8585 res["msg"] = str(msg) 8686 return res 8787 #将运行返回的结果,根据自己需要,需要要哪些结果就把哪些结果写入拷贝的那份Excel中 8888 def wirte_result(result, filename="D:\Business_ManageMent\Case\\result.xlsx"): 8989 # 返回结果的行数row_nub 9090 row_nub = result['rowNum'] 9191 # 写入statuscode 9292 wt = Write_excel(filename) 9393 wt.write(row_nub, 7, result['statuscode']) # 写入返回状态码statuscode,89494 wt.write(row_nub, 12, result['times']) # 耗时 9595 wt.write(row_nub, 14, result['error']) # 状态码非200时的返回信息 9696 wt.write(row_nub, 13, result['result']) # 测试结果 pass 还是fail 9797 wt.write(row_nub, 15, result['msg']) # 抛异常

四、定义发送邮件和创建测试用例套件

1 1 import time,os 2 2 import smtplib 3 3 import unittest 4 4 from Commons import HTMLTestRunner_jpg 5 5 from email.header import Header 6 6 from email.mime.text import MIMEText 7 7 from email.mime.multipart import MIMEMultipart 8 8 import email.mime.multipart 9 9 from email.mime.application import MIMEApplication 1010 from Case import * 1111 1212 # test_dir = os.path.abspath(os.path.join(os.getcwd(), "..")) 1313 # now = time.strftime('%y_%m_%d %H_%M_%S') 1414 # filename = (os.path.abspath('../Report') + '\\' + now + 'result.html') 1515 # print(filename) 1616 # fp = open(filename, 'wb') 1717 import sys,os 1818 curPath = os.path.abspath(os.path.dirname(__file__)) 1919 rootPath = os.path.split(curPath)[0] 2020 sys.path.append(rootPath) 2121 #定义发送邮件 2222 class Send(): 2323 def __init__(self): 2424 self.flie_dir=rootPath+'\Report' 2525 self.lists = os.listdir(self.flie_dir) 2626 #将所有的报告按时间从小到大大排序 2727 self.lists.sort(key=lambda fn: os.path.getmtime(self.flie_dir + '\\' + fn)) 2828 #取报告集合中最后一个报告即为最新的测试报告 2929 self.new_file = os.path.join(self.flie_dir, self.lists[-1]) 3030 def send_mail(self): 3131 now=time.strftime('%y:%m:%d:%H:%M:%S') 3232 sender = '1063126729@qq.com' 3333 recever= 'steve@wemart.cn' 3434 msg = MIMEMultipart() 3535 content = '最新接口测试报告,详情请下载附件查看,生成时间为:%s'%(now) 3636 txt = email.mime.text.MIMEText(content, 'plain', 'utf-8') 3737 msg.attach(txt) 3838 msg['Subject']='接口自动化测试报告' 3939 msg['date']=now 4040 #添加附件 4141 att = MIMEText(open(self.new_file, "rb").read(), "base64", "utf-8") 4242 att["Content-Type"] = "application/octet-stream" 4343 att["Content-Disposition"] = 'attachment; filename= "Report.html"' 4444 msg.attach(att) 4545 server=smtplib.SMTP_SSL(port=465) 4646 server.connect('smtp.qq.com') 4747 server.login('1063126729@qq.com','lhrcqszwzqafbcjf') 4848 server.sendmail(sender,recever,msg.as_string()) 4949 server.quit() 5050 print('邮件已发送') 5151 #创建一个测试套件,将所有的用例添加到测试套件 5252 def creatsuit(slef): 5353 test_dir =rootPath+'\Case' 5454 suit=unittest.TestSuite() 5555 discover=unittest.defaultTestLoader.discover(test_dir,pattern='test*.py',top_level_dir=None) 5656 for test_suit in discover: 5757 for case in test_suit: 5858 suit.addTest(case) 5959 return suit

 这里说明一下,excel表格自己新建一份,名字命名好,表头各个字段自己喜欢命名啥就命名啥,但注意代码中涉及到表头字段的也要相应调整,保持俩者一致。下面我贴出我存放用例的excel表格样式,供参考:

A:控制开关case    B:case名称   C:接口请求方法  D:接口地址  E:传参类型    F:请求头   G:状态码   H:检查点    I:get请求是传的参数     J:post请求时传的参数   K可以不要,这是我当时调试用的

L:接口响应时间  M:运行结果失败获成功   N:提示接口报错     O:接口返回的报错信息     其中G、L、M、N、O是不用填写的,这是为了复制该份表格时,要写入数据到复制的那份表格中用的

五、前四部分都是一些封装的东西,都是为了第五部分调用准备的,下面的代码是利用unittest框架去组织测试用例,因为我通过ddt数据驱动的,所以这部分代码就比较简洁了,如果你把测试数据都写在代码中,这是不利于维护的,看上去也很繁琐,几千条测试用例那要写多少

1 1 import unittest 2 2 import ddt 3 3 import os 4 4 import requests 5 5 from Commons import base_api 6 6 from Tool_class import read_excel_fz 7 7 from Tool_class import writeexcel_fz 8 8 from Case.Hand_code_case.Login_case.Test_stor_login02 import * 9 9 import os,copy 1010 1111 #获取当前文件位置路径 1212 curpath = os.path.dirname(os.path.realpath(__file__)) 1313 # 获取TestCase.xlsx路径 1414 testxlsx = os.path.join(curpath, "TestCase.xlsx") 1515 #获取curpath位置的上一层目录位置 1616 report_path = os.path.join(os.path.dirname(curpath)) 1717 #获取测试结果表格的目录位置 1818 reportxlsx = os.path.join(report_path, "result.xlsx") 1919 #创建读取表格的对象 2020 testdata = read_excel_fz.ExcelUtil(testxlsx) 2121 #获取表格中需要运行的数据或不需要运行的数据 2222 cases=testdata.open_case() 2323 #表格中打开的case 2424 case=cases[0] 2525 #表格中关闭的case 2626 case_mobile=cases[1] 2727 2828 2929 @ddt.ddt 3030 class Test_api(unittest.TestCase): 3131 u'''B2C-API''' 3232 @classmethod 3333 def setUpClass(cls): 3434 # 如果有登录的话,就在这里先登录了 3535 cls.s = requests.Session() 3636 # 复制xlsx 3737 writeexcel_fz.Copy_excel(testxlsx, reportxlsx) 3838 3939 #采用装饰器,在运行case之前都会先运行这个,这里的case是表格里打开的用例,也就是我需要运行的数据 4040 @ddt.data(*case) 4141 def test_api_01(self, data): 4242 #先复制excel数据到Case文件夹下面 4343 res = base_api.send_requests(self.s, data) 4444 base_api.wirte_result(res, filename=reportxlsx) 4545 #检查点 checkpoint 4646 check = data["checkpoint"] 4747 print("检查点->:%s"%check) 4848 #返回结果 4949 res_text = res["text"] 5050 print("返回实际结果->:%s"%res_text) 5151 #将接口返回的结果的键和值取到,通过键是否存在,再利用返回的值去和预期结果做断言 5252 for m,n in res_text.items(): 5353 if m=='data' and m=='msg': 5454 self.assertTrue(res_text['data']!=None) 5555 self.assertTrue(res_text['msg'] == check) 5656 elif 'data' not in m: 5757 self.assertTrue(res_text['msg']==check)

六、上面将用例组织好了,接下来就是通过HTMLTestRunner模块运行并生成报告了,注:HTMLTestRunner模块自己去百度下载,可以将内容直接复制,然后在你的工程目录下建一个py文件将内容拷贝进去即可

1 1 import sys,os 2 2 curPath = os.path.abspath(os.path.dirname(__file__)) 3 3 rootPath = os.path.split(curPath)[0] 4 4 sys.path.append(rootPath) 5 5 6 6 import unittest,time,os 7 7 from Commons import HTMLTestRunner_jpg 8 8 from email.header import Header 9 9 from email.mime.text import MIMEText 1010 from Commons.send_mail_report import Send 1111 1212 #定义一个当前时间戳 1313 now = time.strftime('%y_%m_%d %H_%M_%S') 1414 #以时间给报告命名,这样就不会重复了 1515 filename = rootPath+'\Report'+'\\'+ now + 'result.html' 1616 fp=open(filename,'wb') 1717 a = Send() 1818 runner = HTMLTestRunner_jpg.HTMLTestRunner(stream=fp, title='测试报告', description='执行情况:') 1919 runner.run(a.creatsuit()) 2020 fp.close() 2121 #调用发送邮件的方法 2222 a.send_mail()

 七、Jenkins配置

然后回到任务首页,点击任务后面按钮立即构建,打开控制台即可查看运行记录和结果,如图:

以上所有的步骤已经完成了整个项目的构建,大家针对自己的项目可以拿上面的代码加以修改,其实最重要的是思路和良好的代码基础,我没有针对工具安装进行详细说,这个自己百度!自动化并不难,教程也很多,要学会加以总结并融汇贯通。后期主要跟新我学Python的历程,从基础到高级,再到利用Python实战做项目,欢迎关注

点赞
收藏

评论区

加载中...

相关推荐

python读取excel数据转为json格式

做自动化时需要从excel读取数据;本文实现将excel文件数据读取为json格式,方便自动化调用读取xls文件使用xlrd读取xls文件代码:pythonimportxlrddefreadxls(file):实例化excelbookxlrd.openworkbook(file)下标读取sheetsheetb

C#读取Excel以及将数据导入至Excel

一,读取Excel文件内容:1//根据excle的路径把第一个sheel中的内容放入datatable2publicstaticDataTableReadExcelToTable()//excel存放的路径3{4//连接字

Java读取word中表格

  因为要新建一个站,公司要把word表格的部分行列存到数据库中。之前用java操作过excel,本来打算用java从word表格中读取数据,再存到数据库中,结果因为权限不够,无法访问公司要写的那个数据库,跪了跪了。  但还是把java读取word中表格的方法写一下,先上代码。publicstaticvoidtestWord(Strin

Python 操作excel

python操作excel使用xlrd、xlwt和xlutils模块。xlrd模块是读取excel的,xlwt模块是写excel的,xlutils是用来修改excel的一、python 读取excelimportxlrdbookxlrd.open_workbook('all_stu.xls')打开一个excelsheetb

Python操作Excel

前言:Python操作Excel使用openpyxl模块,python中有好几个与excel相关操作的模块。xlrd库:从excel中读取数据,支持xls、xlsx格式。xlwt库:对excel进行修改操作,不支持对xlsx格式的修改。xlutils库:在xlrd和xlwd中对一个已存在的文件进行修改。openpyxl库:

Python之CSV模块

1\.CSV简介CSV(CommaSeparatedValues)是逗号分隔符文本格式,常用于Excel和数据库的导入和导出,Python标准库的CSV模块提供了读取和写入CSV格式文件的对象。1.1csv.reader对象和csv文件的读取