【介面自動化】Python+Requests介面自動化測試框架搭建【三】
經過上兩篇文章的講解,我們已經完成介面自動化的基礎框架,現在開始根據實際專案豐滿起來。
在PyCharm中新建專案,專案工程結構如下:
config:配置資料夾,可以將一些全域性變數放於配置檔案中,方便呼叫。例如:URL地址、埠,開發如經常更換埠在配置檔案中便可修改。
data:測試用例表格資料夾,存放測試用例.xls和讀取寫入excel表的檔案。
demo:程式公共類資料夾,存放程式公共類,例如:POST/GET請求,獲取Token等。
kit:相關測試工具,壓縮、傳送郵件。
main:程式執行主資料夾。
report:測試報告資料夾。
test_case:測試用例。
公司實際開發專案中,存在介面依賴,即Token。Token獲取方法為登入後返回Token值,所以我們編寫一個登入類獲取Token,並將Token放置於config檔案中,成為全域性變數,等其他介面呼叫時,直接引用變數。
在demo中新建DemoMain請求方法公共類。
DemoMain.py
#!/usr/bin/env python # encoding: utf-8 ''' @author: GongYu @license: (C) Copyright 2020 @contact: [email protected] @software: PyCharm @file: DemoMain.py @time: 2020/7/31 10:58 @desc: 公共方法主類 ''' import requests class RunMain: def __init__(self): pass @staticmethoddef send_post(url,cookies,headers,params=None): try: res = requests.post(url=url,cookies=cookies,headers=headers,data=params) return res.status_code # 返回響應狀態程式碼 except Exception as msg: return msg @staticmethod def send_get(url,cookies,headers,params=None,):try: res = requests.get(url=url,cookies=cookies,headers=headers,params=params,) return res.status_code # 返回響應狀態程式碼 except Exception as msg: return msg def run_main(self, url,method,cookies=None,headers=None,params=None): if method == 'GET': res = self.send_get(url,cookies,headers,params) return res elif method == 'POST': res = self.send_post(url,cookies,headers,params) return res else: print('不支援的請求方式!')
CaseDemo.py 根據介面分開編寫請求方法
實際開發中遇到的問題(僅為自己記錄):
1.return返回值的問題:實際專案測試中我們不能只返回code狀態碼,因為介面測試中不能只憑返回狀態碼進行斷言,我們測試判定中還應檢查介面返回值,介面返回值應在開發提供介面文件已經註明。所以上述程式碼中我們應將返回值改為res。
2.因為一開始只考慮斷言狀態碼的問題,所以導致多新建一個LoginDemo請求類,如返回值為res,此檔案即可刪除。
3.配置檔案中可以參考Postman中多種引數的方式進行配置,可根據實際專案自己增加,極其方便。還可以配置資料庫等資訊,不再贅述。
data資料夾:
GetExcel.py:獲取測試用例操作類
#!/usr/bin/env python # encoding: utf-8 ''' @author: GongYu @license: (C) Copyright 2020 @contact: [email protected] @software: PyCharm @file: GetExcel.py @time: 2020/8/12 17:03 @desc:獲取Excel表格資料 ''' import xlrd def get_excel_data(sheetName,idCol=0,bodyCol=7,repsCol=9): # 獲取資料函式 dataList = [] # 生成一個空字典 workSheet = xlrd.open_workbook('../data/JDData.xls', formatting_info=True).sheet_by_name(sheetName) # 獲取表格 endRow = workSheet.nrows # 獲取有效工作行數 for one in range(1, endRow): # 迴圈獲取 if workSheet.cell(one,12).value == 'Yes': # 判斷用例是否執行 dataList.append((workSheet.cell(one, idCol).value,workSheet.cell(one, bodyCol).value, workSheet.cell(one, repsCol).value)) # 追加dataList else: pass return dataList
固定讀取表格中的資料即:第1列,第8列,第10列資料,所以形參寫死。
SetExcel.py:測試結果寫入Excel表格
#!/usr/bin/env python # encoding: utf-8 ''' @author: GongYu @license: (C) Copyright 2020 @contact: [email protected] @software: PyCharm @file: SetExcel.py @time: 2020/8/14 17:01 @desc: 寫入Excel ''' import xlrd import json from xlutils import copy class CSetExcel(): def SetExcel(self,sheetName,infodata,one,Col=10): path = '../data/JDData.xls' workSheet = xlrd.open_workbook(path,formatting_info=True) New_workSheet = copy.copy(workSheet) # 複製表格 New_Sheet = New_workSheet.get_sheet(sheetName) # 獲取表格名 New_Sheet.write(one,Col,json.dumps(infodata,ensure_ascii=False)) # 寫入Excel New_workSheet.save(path) # 儲存
此處坑:
1.New_Sheet.write(one,Col,json.dumps(infodata,ensure_ascii=False)) # 寫入Excel
如不加ensure_ascii=False,寫入Excel中中文會被轉義unicode編碼。json.dumps(infodata):介面返回值為字典型別(dict)轉換成字串型別寫入excel。
2.執行方法前,記得關閉Excel表格。
Data.excel模板格式
此處坑:(MD,我也不知道我為啥這麼多坑踩.........心累啊,前人種樹後人乘涼,我先填為敬。)
編號一列單元格格式為文字,不要設定成數值,設定成數值會被Python取出後變為1.0(浮點型),然後導致的結果就是SetExcel.py根據編號寫入資料時,無法識別1.0單元格在哪裡,出現錯誤。
kit資料夾:存放測試報告壓縮工具類以及傳送郵件類
ZipTool.py 壓縮檔案工具類
#!/usr/bin/env python # encoding: utf-8 ''' @author: GongYu @license: (C) Copyright 2020 @contact: [email protected] @software: PyCharm @file: ZipTool.py @time: 2020/8/19 9:52 @desc: 壓縮資料夾工具 ''' import os import zipfile import shutil class FileZip(): def File(self,source_dir, output_filename):# 打包目錄為zip檔案(未壓縮) if os.path.exists('../report/Report.zip') == True : # 判斷檔案是否存在 print("報告壓縮檔案存在!正在執行刪除........") os.remove('../report/Report.zip') # 刪除檔案 print("刪除成功!正在執行打包操作........") zipf = zipfile.ZipFile(output_filename, 'w') pre_len = len(os.path.dirname(source_dir)) for parent, dirnames, filenames in os.walk(source_dir): for filename in filenames: pathfile = os.path.join(parent, filename) arcname = pathfile[pre_len:].strip(os.path.sep) # 相對路徑 zipf.write(pathfile, arcname) zipf.close() shutil.move('../main/Report.zip', '../report') # 移動檔案 print('打包完成,正在傳送報告......') else: print('正在執行打包操作......') zipf = zipfile.ZipFile(output_filename, 'w') pre_len = len(os.path.dirname(source_dir)) for parent, dirnames, filenames in os.walk(source_dir): for filename in filenames: pathfile = os.path.join(parent, filename) arcname = pathfile[pre_len:].strip(os.path.sep) zipf.write(pathfile, arcname) zipf.close() shutil.move('../main/Report.zip', '../report') print('打包完成,正在傳送報告......')
EmailTool.py 傳送郵件工具類
#!/usr/bin/env python # encoding: utf-8 ''' @author: GongYu @license: (C) Copyright 2020 @contact: [email protected] @software: PyCharm @file: EmailTool.py @time: 2020/8/19 9:53 @desc: 傳送郵件工具 ''' import smtplib import time from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.header import Header class SendEmail(): def Email(slef): # 第三方 SMTP 服務 mail_host = "smtp.163.com" # 設定伺服器 mail_user = "[email protected]" # 使用者名稱 mail_pass = " " # 口令 sender = '[email protected]' receivers = ['[email protected]','[email protected]'] # 接收郵件,可設定為你的QQ郵箱或者其他郵箱,多郵箱設定為陣列 message = MIMEMultipart() message['From'] = Header("GongYu", 'utf-8') #message['To'] = Header("測試", 'utf-8') ReportTime = time.strftime("%Y-%m-%d %H:%M") subject = '['+ReportTime +']介面自動化測試報告' message['Subject'] = Header(subject, 'utf-8') # 郵件正文內容 NewTime = time.strftime("%Y-%m-%d %H:%M") message.attach(MIMEText('各位領導,同事:附件內容為介面自動化測試報告。測試時間為:'+NewTime+',請下載檢視!', 'plain', 'utf-8')) # 附件 att1 = MIMEText(open('../data/Data.xls', 'rb').read(), 'base64', 'utf-8') att1["Content-Type"] = 'application/octet-stream' att1["Content-Disposition"] = 'attachment; filename="JDData.xls"' message.attach(att1) att2 = MIMEText(open('../report/Report.zip', 'rb').read(), 'base64', 'utf-8') att2["Content-Type"] = 'application/octet-stream' att2["Content-Disposition"] = 'attachment; filename="Report.zip"' message.attach(att2) try: smtpObj = smtplib.SMTP() smtpObj.connect(mail_host, 25) # 25 為 SMTP 埠號 smtpObj.login(mail_user, mail_pass) smtpObj.sendmail(sender, receivers, message.as_string()) print("郵件傳送成功!") except smtplib.SMTPException: print("Error: 無法傳送郵件")
下面我們編寫Test_case.py 檔案,放置於test_case資料夾下
Test_case.py
#!/usr/bin/env python # encoding: utf-8 ''' @author: GongYu @license: (C) Copyright 2020 @contact: [email protected] @software: PyCharm @file: Test_test.py @time: 2020/8/13 9:25 @desc: 測試執行 ''' import json import pytest import allure from data.GetExcel import get_excel_data from data.SetExcel import CSetExcel from demo.CaseDemo import addapi @allure.feature('地址介面測試') class Testaddapi(): @allure.story('獲取一級地址') @pytest.mark.parametrize('idData,infoData,resultdata',get_excel_data('1-獲取一級地址')) def test_getProvince(self,idData,infoData,resultdata): Res = addapi().getProvince() CSetExcel().SetExcel('1-獲取一級地址', Res.json(), json.loads(idData)) assert Res.status_code == 200 assert Res.json()['resultMessage'] == json.loads(resultdata)['resultMessage'] assert Res.json()['success'] == json.loads(resultdata)['success']
我們採用的是Pytest測試框架,使用allure輸出測試報告。
到這裡我們的測試框架就已經完成了,下面我們編寫一個執行主類:TestMain.py 進行啟動測試。
#!/usr/bin/env python # encoding: utf-8 ''' @author: GongYu @license: (C) Copyright 2020 @contact: [email protected] @software: PyCharm @file: TestMain.py @time: 2020/8/13 10:32 @desc: 執行主類 ''' import shutil import pytest import os from kit.ZipTool import FileZip from kit.EmailTool import SendEmail if __name__ == '__main__': # 啟動allure if os.path.exists('../report/xml') == True or os.path.exists('../report/html') == True: print("報告目錄存在!正在執行刪除........") shutil.rmtree(r'../report/xml') shutil.rmtree(r'../report/html') print("刪除成功!正在執行測試用例........") pytest.main(['../test_case/Test_test.py', '-s', '--alluredir', '../report/xml']) # 生成測試報告檔案 print('測試報告轉換HTML.....') os.system('allure generate ../report/xml -o ../report/html') # 將測試報告檔案轉化為HTML FileZip().File('../report', 'Report.zip') SendEmail().Email() os.system('allure serve ../report/xml') # 執行測試報告檔案 else: print('正在執行測試用例........') pytest.main(['../test_case/Test_test.py', '-s', '--alluredir', '../report/xml']) print('測試報告轉換HTML.....') os.system('allure generate ../report/xml -o ../report/html') FileZip().File('../report', 'Report.zip') SendEmail().Email() os.system('allure serve ../report/xml')
下面我們執行試一下:
控制檯輸出:
Allure測試報告:
下面我們登入一下郵箱檢視一下:
我們已經將測試結果加入附件傳送到了負責人的郵箱,到此我們的自動化測試框架已經完成。最後還有一個日誌功能還沒實現,等找個時間再來補充吧。
新手上路,知識不足,如有紕漏錯誤,還請大神們指正,謝謝各位咯~~~