本次寫的是針對有代碼基礎的,沒基礎建議先去學基礎,如下全部描述內容都是我已經在公司項目實踐成功的!僅供參考html
總體思路:
一、接口自動化用的是Python中unittest框架
二、全部的測試數據用例存放Excel表
三、封裝一套讀取和寫入的Excel方法
四、重寫request方法(爲了從Excel讀取數據後對數據做分析和判斷並在測試報告生成相關信息)git
五、經過HTMLTestRunner運行測試用例生成網頁版報告
六、將自動化腳本放到公司git上,方便其餘人員獲取你的代碼進行編寫腳本,後面會具體講如何獲取代碼和提交代碼(讓運維人員給你開通個git帳號,本身註冊登陸就能夠了)
七、經過Jenkins構建任務,定時自動運行git上自動化腳本,後面會具體講如何配置Jenkinsjson
先看看個人接口自動化整個目錄結構和每一個文件具體是幹嗎的:api
1、讀取表格的代碼:app
1 import xlrd,os,copy 2 3 import sys,os 4 5 #這三行代碼是解決文件路徑問題 6 7 curPath = os.path.abspath(os.path.dirname(__file__)) 8 9 rootPath = os.path.split(curPath)[0] 10 11 sys.path.append(rootPath) 12 13 class ExcelUtil(): 14 15 list=[] 16 17 list1 = [] 18 19 def __init__(self,excelpath,sheetname='Sheet1'): 20 21 self.data=xlrd.open_workbook(excelpath) 22 23 self.table=self.data.sheet_by_name(sheetname) 24 25 #獲取第一行做爲key值 26 27 self.keys=self.table.row_values(0) 28 29 #獲取總行數 30 31 self.rowNum=self.table.nrows 32 33 #獲取總列數 34 35 self.colNum=self.table.ncols 36 37 38 39 #此方法有倆個用處:一、獲取關閉或打開的case 二、不一樣模塊的用例也能夠經過該方法區分開來 40 41 def open_case(self): 42 43 exceldata = ExcelUtil(os.path.abspath(rootPath+'/Case/Ddt_case_api/TestCase.xlsx'), 'Sheet1') 44 45 list = [] 46 47 list1 = [] 48 49 list2=[] 50 51 for i in exceldata.dict_data(): 52 53 a = i['control_case'] # 這是在Excel加的開關case的字段 54 55 if a == '': 56 57 list.append(i) 58 59 elif a=='mobile_請先登陸': 60 61 list1.append(i) 62 63 elif a=='B_請先登陸': 64 65 list2.append(i) 66 67 return list,list1,list2 68 69 # print(len(list)) 70 71 def dict_data(self): 72 73 if self.rowNum<=1: 74 75 print('總行數小於1') 76 77 else: 78 79 r=[] 80 81 j=1 82 83 for i in range(self.rowNum-1): 84 85 s={} 86 87 s['rowNum']=i+2 88 89 values=self.table.row_values(j) 90 91 for x in range(self.colNum): 92 93 s[self.keys[x]]=values[x] 94 95 r.append(s) 96 97 j+=1 98 99 return r 100 101 #經過下面這個入口進行調試 102 103 if __name__=='__main__': 104 105 a=ExcelUtil('D:\Business_ManageMent\Case\Ddt_case_api\TestCase.xlsx') 106 107 b=a.open_case() 108 109 print(b)
2、寫入表格代碼:框架
1 from openpyxl import load_workbook 2 3 import openpyxl 4 5 import xlrd 6 7 8 9 def Copy_excel(exclepath1,excelpath2): 10 11 #把excle1數據複製到excel2 12 13 wb2=openpyxl.Workbook() 14 15 wb2.save(excelpath2) 16 17 wb1=load_workbook(exclepath1) 18 19 wb2=load_workbook(excelpath2) 20 21 sheets1=wb1.sheetnames 22 23 sheets2=wb2.sheetnames 24 25 sheet1=wb1[sheets1[0]] 26 27 sheet2=wb2[sheets2[0]] 28 29 maxrow=sheet1.max_row 30 31 maxcolum=sheet1.max_column 32 33 for m in range(1,maxrow+1): 34 35 for n in range(97,97+maxcolum): 36 37 n=chr(n) 38 39 i='%s%d'%(n,m) 40 41 cell1=sheet1[i].value 42 43 sheet2[i]=cell1 44 45 wb2.save(excelpath2) 46 47 wb1.close() 48 49 wb2.close() 50 51 class Write_excel(): 52 53 def __init__(self,filename): 54 55 self.filename=filename 56 57 self.wb=load_workbook(self.filename) 58 59 #激活sheet 60 61 self.ws=self.wb.active 62 63 def write(self,row_n,col_n,value): 64 65 self.ws.cell(row_n,col_n).value=value 66 67 self.wb.save(self.filename) 68 69 70 71 72 73 #經過下面入口進行調試 74 75 if __name__=='__main__': 76 77 Copy_excel('D:\Business_ManageMent\Case\Ddt_case_api\TestCase.xlsx','D:\Business_ManageMent\Case\\result.xlsx') 78 79 wt=Write_excel('D:\Business_ManageMent\Case\\result.xlsx') 80 81 wt.write(1,2,'hello')
3、重寫request方法及將接口返回結果根據本身的須要寫入拷貝的那張Excel表中運維
1 import json 2 import requests 3 from Tool_class.read_excel_fz import ExcelUtil 4 from Tool_class.writeexcel_fz import Copy_excel, Write_excel 5 6 7 def send_requests(s, testdata): 8 '''封裝requests請求''' 9 #獲取Excel標格中表頭爲method的數據 10 method = testdata["method"] 11 # 獲取Excel標格中表頭爲url的數據 12 url = testdata["url"] 13 try: 14 #eval函數能夠將讀取到的參數內容轉化成字典格式 15 # 獲取Excel標格中表頭爲params的數據 16 params = eval(testdata["params"]) 17 except: 18 params = None 19 # 請求頭部headers 20 try: 21 # 獲取Excel標格中表頭爲headers的數據 22 headers = eval(testdata["headers"]) 23 print("請求頭部:%s" % headers) 24 except: 25 headers = None 26 27 28 # post請求body類型 29 # 獲取Excel標格中表頭爲type的數據 30 type = testdata["type"] 31 # 獲取Excel標格中表頭爲id的數據 32 test_nub = testdata['id'] 33 print("*******正在執行用例:----- %s ----**********" % test_nub) 34 print("請求方式:%s, 請求url:%s" % (method, url)) 35 print("請求params:%s" % params) 36 # post請求body內容 37 try: 38 # 獲取Excel標格中表頭爲body的數據 39 bodydata = eval(testdata["body"]) 40 except: 41 bodydata = {} 42 # 判斷傳data數據仍是json 43 if type == "json": 44 #json.dumps將字典數據轉成json格式,由於不一樣的接口傳遞參數是不一樣的,有的是傳data,有的傳json 45 body= json.dumps(bodydata) 46 elif type == "data": 47 body = bodydata 48 else: 49 body = bodydata 50 51 if type=='json': 52 print("post請求body類型爲:%s ,body內容爲:%s" % (type,body)) 53 elif method=='post': 54 print("post請求body類型爲:%s ,body內容爲:%s" % (type,body)) 55 verify = False 56 res = {} # 接受返回數據 57 58 try: 59 r = s.request(method=method, 60 url=url, 61 params=params, 62 headers=headers, 63 data=body, 64 verify=verify 65 ) 66 print("頁面返回信息:%s" % r.json()) 67 res['id'] = testdata['id'] 68 res['rowNum'] = testdata['rowNum'] 69 res["statuscode"] = str(r.status_code) # 狀態碼轉成str 70 res["text"] = r.json() 71 res["times"] = str(r.elapsed.total_seconds()) # 接口請求時間轉str 72 if res["statuscode"] != "200": 73 res["error"] = "服務錯誤,接口未請求成功" 74 res["msg"] = str(res["text"]) 75 else: 76 res["error"] = "" 77 res["msg"] = "" 78 if testdata["checkpoint"] == res["text"]['msg']: 79 res["result"] = "pass" 80 print("用例測試結果: %s---->%s" % (test_nub, res["result"])) 81 else: 82 res["result"] = "fail" 83 return res 84 except Exception as msg: 85 res["msg"] = str(msg) 86 return res 87 #將運行返回的結果,根據本身須要,須要要哪些結果就把哪些結果寫入拷貝的那份Excel中 88 def wirte_result(result, filename="D:\Business_ManageMent\Case\\result.xlsx"): 89 # 返回結果的行數row_nub 90 row_nub = result['rowNum'] 91 # 寫入statuscode 92 wt = Write_excel(filename) 93 wt.write(row_nub, 7, result['statuscode']) # 寫入返回狀態碼statuscode,第8列 94 wt.write(row_nub, 12, result['times']) # 耗時 95 wt.write(row_nub, 14, result['error']) # 狀態碼非200時的返回信息 96 wt.write(row_nub, 13, result['result']) # 測試結果 pass 仍是fail 97 wt.write(row_nub, 15, result['msg']) # 拋異常
4、定義發送郵件和建立測試用例套件函數
1 import time,os 2 import smtplib 3 import unittest 4 from Commons import HTMLTestRunner_jpg 5 from email.header import Header 6 from email.mime.text import MIMEText 7 from email.mime.multipart import MIMEMultipart 8 import email.mime.multipart 9 from email.mime.application import MIMEApplication 10 from Case import * 11 12 # test_dir = os.path.abspath(os.path.join(os.getcwd(), "..")) 13 # now = time.strftime('%y_%m_%d %H_%M_%S') 14 # filename = (os.path.abspath('../Report') + '\\' + now + 'result.html') 15 # print(filename) 16 # fp = open(filename, 'wb') 17 import sys,os 18 curPath = os.path.abspath(os.path.dirname(__file__)) 19 rootPath = os.path.split(curPath)[0] 20 sys.path.append(rootPath) 21 #定義發送郵件 22 class Send(): 23 def __init__(self): 24 self.flie_dir=rootPath+'\Report' 25 self.lists = os.listdir(self.flie_dir) 26 #將全部的報告按時間從小到大大排序 27 self.lists.sort(key=lambda fn: os.path.getmtime(self.flie_dir + '\\' + fn)) 28 #取報告集合中最後一個報告即爲最新的測試報告 29 self.new_file = os.path.join(self.flie_dir, self.lists[-1]) 30 def send_mail(self): 31 now=time.strftime('%y:%m:%d:%H:%M:%S') 32 sender = '1063126729@qq.com' 33 recever= 'steve@wemart.cn' 34 msg = MIMEMultipart() 35 content = '最新接口測試報告,詳情請下載附件查看,生成時間爲:%s'%(now) 36 txt = email.mime.text.MIMEText(content, 'plain', 'utf-8') 37 msg.attach(txt) 38 msg['Subject']='接口自動化測試報告' 39 msg['date']=now 40 #添加附件 41 att = MIMEText(open(self.new_file, "rb").read(), "base64", "utf-8") 42 att["Content-Type"] = "application/octet-stream" 43 att["Content-Disposition"] = 'attachment; filename= "Report.html"' 44 msg.attach(att) 45 server=smtplib.SMTP_SSL(port=465) 46 server.connect('smtp.qq.com') 47 server.login('1063126729@qq.com','lhrcqszwzqafbcjf') 48 server.sendmail(sender,recever,msg.as_string()) 49 server.quit() 50 print('郵件已發送') 51 #建立一個測試套件,將全部的用例添加到測試套件 52 def creatsuit(slef): 53 test_dir =rootPath+'\Case' 54 suit=unittest.TestSuite() 55 discover=unittest.defaultTestLoader.discover(test_dir,pattern='test*.py',top_level_dir=None) 56 for test_suit in discover: 57 for case in test_suit: 58 suit.addTest(case) 59 return suit
這裏說明一下,excel表格本身新建一份,名字命名好,表頭各個字段本身喜歡命名啥就命名啥,但注意代碼中涉及到表頭字段的也要相應調整,保持倆者一致。下面我貼出我存放用例的excel表格樣式,供參考:工具
A:控制開關case B:case名稱 C:接口請求方法 D:接口地址 E:傳參類型 F:請求頭 G:狀態碼 H:檢查點 I:get請求是傳的參數 J:post請求時傳的參數 K能夠不要,這是我當時調試用的post
L:接口響應時間 M:運行結果失敗獲成功 N:提示接口報錯 O:接口返回的報錯信息 其中G、L、M、N、O是不用填寫的,這是爲了複製該份表格時,要寫入數據到複製的那份表格中用的
5、前四部分都是一些封裝的東西,都是爲了第五部分調用準備的,下面的代碼是利用unittest框架去組織測試用例,由於我經過ddt數據驅動的,因此這部分代碼就比較簡潔了,若是你把測試數據都寫在代碼中,這是不利於維護的,看上去也很繁瑣,幾千條測試用例那要寫多少
1 import unittest 2 import ddt 3 import os 4 import requests 5 from Commons import base_api 6 from Tool_class import read_excel_fz 7 from Tool_class import writeexcel_fz 8 from Case.Hand_code_case.Login_case.Test_stor_login02 import * 9 import os,copy 10 11 #獲取當前文件位置路徑 12 curpath = os.path.dirname(os.path.realpath(__file__)) 13 # 獲取TestCase.xlsx路徑 14 testxlsx = os.path.join(curpath, "TestCase.xlsx") 15 #獲取curpath位置的上一層目錄位置 16 report_path = os.path.join(os.path.dirname(curpath)) 17 #獲取測試結果表格的目錄位置 18 reportxlsx = os.path.join(report_path, "result.xlsx") 19 #建立讀取表格的對象 20 testdata = read_excel_fz.ExcelUtil(testxlsx) 21 #獲取表格中須要運行的數據或不須要運行的數據 22 cases=testdata.open_case() 23 #表格中打開的case 24 case=cases[0] 25 #表格中關閉的case 26 case_mobile=cases[1] 27 28 29 @ddt.ddt 30 class Test_api(unittest.TestCase): 31 u'''B2C-API''' 32 @classmethod 33 def setUpClass(cls): 34 # 若是有登陸的話,就在這裏先登陸了 35 cls.s = requests.Session() 36 # 複製xlsx 37 writeexcel_fz.Copy_excel(testxlsx, reportxlsx) 38 39 #採用裝飾器,在運行case以前都會先運行這個,這裏的case是表格裏打開的用例,也就是我須要運行的數據 40 @ddt.data(*case) 41 def test_api_01(self, data): 42 #先複製excel數據到Case文件夾下面 43 res = base_api.send_requests(self.s, data) 44 base_api.wirte_result(res, filename=reportxlsx) 45 #檢查點 checkpoint 46 check = data["checkpoint"] 47 print("檢查點->:%s"%check) 48 #返回結果 49 res_text = res["text"] 50 print("返回實際結果->:%s"%res_text) 51 #將接口返回的結果的鍵和值取到,經過鍵是否存在,再利用返回的值去和預期結果作斷言 52 for m,n in res_text.items(): 53 if m=='data' and m=='msg': 54 self.assertTrue(res_text['data']!=None) 55 self.assertTrue(res_text['msg'] == check) 56 elif 'data' not in m: 57 self.assertTrue(res_text['msg']==check)
6、上面將用例組織好了,接下來就是經過HTMLTestRunner模塊運行並生成報告了,注:HTMLTestRunner模塊本身去百度下載,能夠將內容直接複製,而後在你的工程目錄下建一個py文件將內容拷貝進去便可
1 import sys,os 2 curPath = os.path.abspath(os.path.dirname(__file__)) 3 rootPath = os.path.split(curPath)[0] 4 sys.path.append(rootPath) 5 6 import unittest,time,os 7 from Commons import HTMLTestRunner_jpg 8 from email.header import Header 9 from email.mime.text import MIMEText 10 from Commons.send_mail_report import Send 11 12 #定義一個當前時間戳 13 now = time.strftime('%y_%m_%d %H_%M_%S') 14 #以時間給報告命名,這樣就不會重複了 15 filename = rootPath+'\Report'+'\\'+ now + 'result.html' 16 fp=open(filename,'wb') 17 a = Send() 18 runner = HTMLTestRunner_jpg.HTMLTestRunner(stream=fp, title='測試報告', description='執行狀況:') 19 runner.run(a.creatsuit()) 20 fp.close() 21 #調用發送郵件的方法 22 a.send_mail()
7、Jenkins配置
而後回到任務首頁,點擊任務後面按鈕當即構建,打開控制檯便可查看運行記錄和結果,如圖:
以上全部的步驟已經完成了整個項目的構建,你們針對本身的項目能夠拿上面的代碼加以修改,其實最重要的是思路和良好的代碼基礎,我沒有針對工具安裝進行詳細說,這個本身百度!自動化並不難,教程也不少,要學會加以總結並融匯貫通。後期主要跟新我學Python的歷程,從基礎到高級,再到利用Python實戰作項目,歡迎關注