用Python實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)的接口自動(dòng)化測試
在接口測試的過程中,很多時(shí)候會(huì)用到對CSV的讀取操作,本文主要說明Python3對CSV的寫入和讀取。
1. 需求
某API,GET方法,token,mobile,email三個(gè)參數(shù)
- token為必填項(xiàng)
- mobile,email 必填其中1項(xiàng)
- mobile為手機(jī)號,email為email格式
2. 方案
針對上面的API,在做接口測試時(shí),需要的測試用例動(dòng)輒會(huì)多達(dá)10+, 這個(gè)時(shí)候采用數(shù)據(jù)驅(qū)動(dòng)的方式將共性的內(nèi)容寫入配置文件或許會(huì)更合適。
這里考慮把API、參數(shù)、以及預(yù)期結(jié)果預(yù)行在格式化的CSV里保存,利用csv組件從CSV里讀取URL、參數(shù)以及預(yù)期結(jié)果,Requests組件發(fā)起請求,將響應(yīng)結(jié)果與預(yù)期結(jié)果進(jìn)行比對,***把比對結(jié)果寫到結(jié)果CSV。
流程如下圖
3. 實(shí)現(xiàn)
(1) 在上代碼之前,先安裝好如下幾個(gè)組件:
- csv 讀寫CSV文件
- json
- requests 發(fā)起請求,獲取響應(yīng)結(jié)果
- unittest 測試用例調(diào)度
(2) data.csv(本示例選取部分用例)
(3) reader_CSV函數(shù)代碼示例
- import csv
- import json
- import requests
- import time
- import unittest
- def readCSV(self,filename):
- '''
- :param filename: 需要讀取的數(shù)據(jù)文件
- :return: [{data1},{data2}...]
- '''
- datas = []
- try:
- #以DictReader的方式讀取數(shù)據(jù)文件,方便與json互做轉(zhuǎn)換
- with open(filename,'r') as csvfile :
- #從文件里讀取到的數(shù)據(jù)轉(zhuǎn)換成字典列表的格式
- reader = csv.DictReader(csvfile)
- for row in reader:
- data = {}
- data['id'] = row['id']
- data['url'] = row['url']
- data['token'] = str(row['token'])
- data['mobile'] = row['mobile']
- data['email'] = row['email']
- data['expect'] = json.dumps(row['expect']) \
- if isinstance(row['expect'],dict) \
- else row['expect'] #如果expect讀取出來的不是json則取其原值,否則轉(zhuǎn)為json格式保存到result里
- datas.append(data)
- return datas
- #如果文件找不到,返回空的datas
- except FileNotFoundError:
- print("文件不存在",filename)
- return datas
(4) request_URL函數(shù)示例(包含GET請求和POST請求2個(gè)方法)
- def get_request(self,url,params):
- '''
- 通用的調(diào)用GET接口方法
- :param url:string 接口路徑
- :param params:{"":"","":""} 需要傳入的參數(shù)
- :return: response響應(yīng)體
- '''
- print("調(diào)用API...")
- r = requests.get(url,paramsparams=params)
- print(r.text)
- return r
- def post_request(self,url,params):
- '''
- 通用的調(diào)用POST接口方法
- :param url: string 接口路徑
- :param params: {"":"","":""} 需要傳入的參數(shù)
- :return:response響應(yīng)體
- '''
- print("調(diào)用API...")
- r = requests.post(url,params=json.dumps(params)) #post的方法必須用json.dumps()轉(zhuǎn)化成json格式
- print(r.text)
- return r
(5) assert_Result函數(shù)示例
- def assertResult(self,except_value,real_value):
- '''
- 校驗(yàn)樣本字符串中是否包含指定字符串
- :param except_value: string 指定字符串
- :param real_value: string 樣本字符串
- :return: Boolean 樣本中包含指定字符串返回True,否則返回False
- '''
- ifsuccess = except_value in str(real_value)
- return ifsuccess
(6) write_CSV函數(shù)示例
- def writeCSV(self,filename,results):
- '''
- 寫入csv文件指定內(nèi)容
- :param filename: string 需要寫入的文件名稱
- :param results: [{data1},{data2},...] 寫入的內(nèi)容
- :return: 無
- '''
- print("寫文件:",filename)
- #以DictWriter的方式寫文件
- with open(filename,'w+') as csvfile:
- headers="id,url,token,mobile,email,expect,real_value,assert_value".split(",")
- writer = csv.DictWriter(csvfile,fieldnames=headers)
- #寫表頭
- writer.writeheader()
- #寫數(shù)據(jù)
- if results.__len__() > 0 :
- for result in results:
- writer.writerow(result)
- csvfile.close()
(7) test_interface1函數(shù)示例
- def test_interface1(self):
- #指定讀取的數(shù)據(jù)文件名稱
- data_file = "../data/data.csv"
- #指定最終結(jié)果生成的數(shù)據(jù)文件名稱
- result_file = "../data/result_{}.csv".format(str(time.time()).split(".")[0])
- #讀取指定文件的數(shù)據(jù)
- datas = self.readCSV(data_file)
- #數(shù)據(jù)文件有內(nèi)容則調(diào)用接口,否則直接測試結(jié)束
- if datas.__len__() > 0:
- results =[]
- #獲取數(shù)據(jù)文件里的每一行
- for testcase in datas :
- result = {}
- result["id"] = testcase["id"]
- result["url"] = testcase["url"]
- result["token"] = testcase["token"]
- result["mobile"] = testcase["mobile"]
- result["email"] = testcase["email"]
- result["expect"] = testcase["expect"]
- #組裝參數(shù)
- params = {
- "token":result["token"],
- "mobile":result["mobile"],
- "email":result["email"]
- }
- #調(diào)用API接口,獲取響應(yīng)結(jié)果
- real_value = self.get_request(result["url"],params)
- #調(diào)用assert方法,檢查預(yù)期結(jié)果是否在響應(yīng)結(jié)果中存在
- assert_value = self.assertResult(result["expect"],real_value.text)
- result["real_value"] = real_value.text
- result["assert_value"] = assert_value
- #獲取每一行里的所有字段以及實(shí)際結(jié)果和驗(yàn)證結(jié)果
- results.append(result)
- #執(zhí)行完所有記錄后,將所有結(jié)果寫入result.csv
- self.writeCSV(result_file,results) #寫入csv文件
- print("測試結(jié)束")
8result_1523956055.csv(本示例中的測試結(jié)果請忽略)
4. 總結(jié)
python封裝了很多方法,對于測試來說開發(fā)速度相對較快,接口自動(dòng)化測試如果采用CSV管理的數(shù)據(jù)驅(qū)動(dòng)方式,使用csv+requests是測試開發(fā)不容錯(cuò)過的利器之一。
【本文是51CTO專欄機(jī)構(gòu)“豈安科技”的原創(chuàng)文章,轉(zhuǎn)載請通過微信公眾號(bigsec)聯(lián)系原作者】