前言
這個季度初的時候,我們公司管理層提出了全面提升部門技術水準的要求,而作為專案開發流程中最重要的一環——測試,我們也是有自己的技術追求的,所以為了,由原來的業務功能測試轉變成自動化測試。之前大多都是手工進行,利用postman和fiddler進行抓包和擷取資料,後來,經過大家的討論,決定基於python學習,開始搞介面自動化,經過大家的努力,這套自動化框架目前已經基本完成了,於是進行一些總結,便於以後回顧溫習,有許多不完善的地方,大家可以留言一起討論研究,共同進步。
首先,我們可以捋一捋思路,想一想介面測試的流程
其次,選擇合適的框架
流程清晰之後,我們需要選擇一個合適的框架,於是選擇了Python3+requests+unittest框架
Requests模組傳送http的網路請求,請求型別主要包含了post,get, PUT,DELETE,HEAD
python+unittest單元測試框架構成,和測試報告生成(HTMLTestRunner)
框架詳解不在此贅述,requests可參考 點選前往
unittest參考 點選前往
基於以上,我們來一步步搭建我們的框架。在這個過程中,我們需要做到業務和資料的分離,這樣才能靈活,達到我們寫框架的目的。接下來,我們來進行結構的劃分。
我們的結構是這樣的
data:存放自動化測試所用到的資料文件log:存放生成的日誌檔案
base:存放公共的方法
report:存放生成的自動化測試報告
testcase:存放測試指令碼
接下來,公共方法的開發
整體結構有了劃分,接下來就該一步步的填充整個框架了,我們先來看看Base檔案中的公共類或函式,這主要用於後續測試case的呼叫,所有公共的、一成不變的資料都可以放在這裡,維護也方便
配置文件如下
[DATABASE]
data_address = ./data/
report_address = ./report/
[HTTP]
base_url = http://xxx.xx
複製程式碼
想知道怎樣從配置文件中得到或寫入相應的資料嗎?那繼續看吧
import os
import configparser
# 獲取當前py檔案地址
proDir = os.path.split(os.path.realpath(__file__))[0]
# 組合config檔案地址
configPath = os.path.join(proDir,"config.ini")
class ReadConfig:
def __init__(self):
#獲取當前路徑下的配置檔案
self.cf = configparser.ConfigParser()
self.cf.read(configPath)
def get_config(self,field,key):
#獲取配置檔案中的key值
result = self.cf.get(field,key)
return result
def set_config(self,field,key,value):
#向配置檔案中寫入配置資訊
fb = open(configPath,'w')
self.cf.set(field,key,value)
self.cf.write(fb)
複製程式碼
那問題又來了,我們的測試資料放在哪裡?怎麼取值?怎麼寫入?怎麼儲存?。。。
別急,接著往下看
測試資料優先考慮放在excel或database中,此處以excel為例做個簡單介紹
這裡需要用到兩個操作表格的庫,xlrd資料驅動的讀取,作用於excel文件,但xlrd不能寫入資料,所以引入xlutils資料驅動的讀取和寫入
安裝方法可以用pip3 install xlrd和pip3 install xlutils 來安裝。
import xlrd
import xlutils.copy
from Base.readConfig import ReadConfig
import time
class ReadExcel:
def __init__(self,section,field,sheet):
# 開啟工作表,並定位到sheet
data_address = ReadConfig().get_config(section,field)
workbook = xlrd.open_workbook(data_address)
self.table = workbook.sheets()[sheet]
def get_rows(self):
# 獲取excel行數
rows = self.table.nrows
return rows
def get_cell(self,row,col):
# 獲取單元格資料
cell_data = self.table.cell(row,col).value
return cell_data
def get_col(self,col):
# 獲取整列資料
col_data = self.table.col_value(col)
return col_data
class WriteExcel:
def __init__(self,section,field,sheet):
# 開啟工作表
self.address = ReadConfig().get_config(section,field)
self.workbook = xlrd.open_workbook(self.address)
self.wf = xlutils.copy.copy(self.workbook)
self.ws = self.wf.get_sheet(sheet)
def set_cell(self,row,col,value):
#設定單元格資料
self.ws.write(row,col,value)
def save_excel(self,filename,format):
#獲取當前時間
self.time = time.strftime("%Y%m%d%H%M%S", time.localtime())
#生成檔案的檔名及格式
self.report = filename + '_' +self.time + format
#儲存檔案
self.wf.save(self.report)
複製程式碼
然後,測試指令碼的編輯
一切準備就緒,下面通過一個簡單的、完整的程式碼進行演示公共函式的呼叫,框架的使用及報告的生成
import unittest
import requests
from Base.readConfig import ReadConfig
from Base.readExcel import ReadExcel
from Base.readExcel import WriteExcel
#例項化
readexcel = ReadExcel('DATABASE','data_address',0)
writeexcel = WriteExcel('DATABASE','data_address',0)
class testcase(unittest.TestCase):
#初始化
def setUp(self):
#獲取url
self.base_url = ReadConfig().get_config('HTTP', 'base_url')
self.url = self.base_url + readexcel.get_cell(1,1)
#獲取請求頭
self.headers = readexcel.get_cell(1,4)
def test_case(self):
nok = 0
ner = 0
# 迴圈讀取excel中的測試資料,進行結果驗證,並生成excel形式的測試報告
for i in range(3,readexcel.get_rows()):
#傳送網路請求,得到響應值
response = requests.post(self.url, headers=self.headers, data=readexcel.get_cell(i,4).encode('utf-8'))
actualresult = response.json()
#獲取excel中的預期結果
expectresult = eval(readexcel.get_cell(i,6))
# 獲取需驗證的資料
key = eval(readexcel.get_cell(i, 5))
keylen = len(key)
j = 0
for k in range(keylen):
aresult = 'actualresult' + key[k]
eresult = 'expectresult' + key[k]
if eval(aresult) == eval(eresult):
#預期結果和實際結果一致
j = j + 1
if j == keylen:
#測試資料執行通過
nok = nok + 1
writeexcel.set_cell(i, 8, 'SUCCESS')
else:
# 測試資料執行失敗,並將實際結果寫入excel
ner = ner + 1
writeexcel.set_cell(i, 8, 'FAILURE')
writeexcel.set_cell(i, 7, str(actualresult))
print('第', i + 1, '行用例執行失敗:預期結果是', expectresult, '實際結果是', actualresult)
# 儲存測試報告
writeexcel.save_excel('testreport', '.xls')
print('測試資料中總共', nok, '條用例執行通過', ner, '條用例執行失敗')
#釋放資源
def tearDown(self):
pass
if __name__ == '__main__':
#構造測試集合
suite = unittest.TestSuite()
suite.addTest(testcase('test_case'))
#建立html檔案
filename = ReadConfig().get_config('DATABASE', 'report_address') + 'testreport.html'
fb = open(filename,"wb")
#執行測試並生成html測試報告
runner = HTMLTestRunner.HTMLTestRunner(stream = fb,description = '針對介面的描述資訊',title = '某某的自動化測試報告')
runner.run(suite)
#關閉檔案
fb.close()
複製程式碼
最後,生成的html報告
以上是最近總結的部分成果,希望對大家有幫助,後續會陸續更新,也請大家多多留言,互相交流互相成長