python http接口自動(dòng)化腳本詳解
今天給大家分享一個(gè)簡(jiǎn)單的python腳本,使用python進(jìn)行http的接口測(cè)試,腳本很簡(jiǎn)單,邏輯是:讀取excel寫好的測(cè)試用例,然后根據(jù)excel中的用例內(nèi)容進(jìn)行調(diào)用,判斷預(yù)期結(jié)果中的返回值是否和返回報(bào)文中的值一致,如果不一致則根據(jù)用例標(biāo)題把bug提交到bug管理系統(tǒng),這里使用的bug管理系統(tǒng)是bugfree。
實(shí)現(xiàn)步驟:
1、讀取excel,保存測(cè)試用例中的內(nèi)容;
2、根據(jù)excel中的請(qǐng)求url和參數(shù)拼接請(qǐng)求報(bào)文,調(diào)用接口,并保存返回報(bào)文;
3、讀取返回報(bào)文,和預(yù)期結(jié)果對(duì)比,不一致的往bugfree數(shù)據(jù)庫(kù)中寫入一條bug,并且把請(qǐng)求報(bào)文、返回報(bào)文和測(cè)試結(jié)果寫到測(cè)試用例的excel中。
http接口最常用的兩種請(qǐng)求方式,POST和GET兩種方法,請(qǐng)求都是類似下面例子的url。
例子:http://127.0.0.1:8080/rest/login?oper_no=marry&id=10
需要用的到幾個(gè)模塊,requests、xlrd(讀取excel)、xlutils(寫excel)、MySQLdb(連接數(shù)據(jù)庫(kù))這四個(gè)模塊都是第三方模塊,需要自己?jiǎn)为?dú)安裝,用到的一些python中的方法和內(nèi)置函數(shù)也都做了說(shuō)明,本文使用的python版本是python2.7。
首先先寫好excel的用例模板,需要有的字段 項(xiàng)目、用例id、接口名稱、用例描述、請(qǐng)求方式、url請(qǐng)求地址、請(qǐng)求參數(shù)(多個(gè)的參數(shù)話用;分號(hào)隔開)、結(jié)果驗(yàn)證(多個(gè)的參數(shù)話用;分號(hào)隔開)、請(qǐng)求報(bào)文、返回報(bào)文、測(cè)試人員、測(cè)試結(jié)果,測(cè)試用例截圖如下:

整體代碼如下,注釋加的很詳細(xì)了
# -*- coding:utf-8 -*-
import requests, xlrd, MySQLdb, time, sys
#導(dǎo)入需要用到的模塊
from xlutils import copy
#從xlutils模塊中導(dǎo)入copy這個(gè)函數(shù)
def readExcel(file_path):
'''''
讀取excel測(cè)試用例的函數(shù)
:param file_path:傳入一個(gè)excel文件,或者文件的絕對(duì)路徑
:return:返回這個(gè)excel第一個(gè)sheet頁(yè)中的所有測(cè)試用例的list
'''
try:
book = xlrd.open_workbook(file_path)#打開excel
except Exception,e:
#如果路徑不在或者excel不正確,返回報(bào)錯(cuò)信息
print '路徑不在或者excel不正確',e
return e
else:
sheet = book.sheet_by_index(0)#取第一個(gè)sheet頁(yè)
rows= sheet.nrows#取這個(gè)sheet頁(yè)的所有行數(shù)
case_list = []#保存每一條case
for i in range(rows):
if i !=0:
#把每一條測(cè)試用例添加到case_list中
case_list.append(sheet.row_values(i))
#調(diào)用接口測(cè)試的函數(shù),把存所有case的list和excel的路徑傳進(jìn)去,因?yàn)楹竺孢€需要把返回報(bào)文和測(cè)試結(jié)果寫到excel中,
#所以需要傳入excel測(cè)試用例的路徑,interfaceTest函數(shù)在下面有定義
interfaceTest(case_list,file_path)
def interfaceTest(case_list,file_path):
res_flags = []
#存測(cè)試結(jié)果的list
request_urls = []
#存請(qǐng)求報(bào)文的list
responses = []
#存返回報(bào)文的list
for case in case_list:
'''''
先遍歷excel中每一條case的值,然后根據(jù)對(duì)應(yīng)的索引取到case中每個(gè)字段的值
'''
try:
'''''
這里捕捉一下異常,如果excel格式不正確的話,就返回異常
'''
#項(xiàng)目,提bug的時(shí)候可以根據(jù)項(xiàng)目來(lái)提
product = case[0]
#用例id,提bug的時(shí)候用
case_id = case[1]
#接口名稱,也是提bug的時(shí)候用
interface_name = case[2]
#用例描述
case_detail = case[3]
#請(qǐng)求方式
method = case[4]
#請(qǐng)求url
url = case[5]
#入?yún)?
param = case[6]
#預(yù)期結(jié)果
res_check = case[7]
#測(cè)試人員
tester = case[10]
except Exception,e:
return '測(cè)試用例格式不正確!%s'%e
if param== '':
'''''
如果請(qǐng)求參數(shù)是空的話,請(qǐng)求報(bào)文就是url,然后把請(qǐng)求報(bào)文存到請(qǐng)求報(bào)文list中
'''
new_url = url#請(qǐng)求報(bào)文
request_urls.append(new_url)
else:
'''''
如果請(qǐng)求參數(shù)不為空的話,請(qǐng)求報(bào)文就是url+?+參數(shù),格式和下面一樣
http://127.0.0.1:8080/rest/login?oper_no=marry&id=100,然后把請(qǐng)求報(bào)文存到請(qǐng)求報(bào)文list中
'''
new_url = url+'?'+urlParam(param)#請(qǐng)求報(bào)文
'''''
excel里面的如果有多個(gè)入?yún)⒌脑挘瑓?shù)是用;隔開,a=1;b=2這樣的,請(qǐng)求的時(shí)候多個(gè)參數(shù)要用&連接,
要把;替換成&,所以調(diào)用了urlParam這個(gè)函數(shù),把參數(shù)中的;替換成&,函數(shù)在下面定義的
'''
request_urls.append(new_url)
if method.upper() == 'GET':
'''''
如果是get請(qǐng)求就調(diào)用requests模塊的get方法,.text是獲取返回報(bào)文,保存返回報(bào)文,
把返回報(bào)文存到返回報(bào)文的list中
'''
print new_url
results = requests.get(new_url).text
print results
responses.append(results)
'''''
獲取到返回報(bào)文之后需要根據(jù)預(yù)期結(jié)果去判斷測(cè)試是否通過(guò),調(diào)用查看結(jié)果方法
把返回報(bào)文和預(yù)期結(jié)果傳進(jìn)去,判斷是否通過(guò),readRes方法在下面定義了。
'''
res = readRes(results,res_check)
else:
'''''
如果不是get請(qǐng)求,也就是post請(qǐng)求,就調(diào)用requests模塊的post方法,.text是獲取返回報(bào)文,
保存返回報(bào)文,把返回報(bào)文存到返回報(bào)文的list中
'''
results = requests.post(new_url).text
responses.append(results)
'''''
獲取到返回報(bào)文之后需要根據(jù)預(yù)期結(jié)果去判斷測(cè)試是否通過(guò),調(diào)用查看結(jié)果方法
把返回報(bào)文和預(yù)期結(jié)果傳進(jìn)去,判斷是否通過(guò),readRes方法會(huì)返回測(cè)試結(jié)果,如果返回pass就
說(shuō)明測(cè)試通過(guò)了,readRes方法在下面定義了。
'''
res = readRes(results,res_check)
if 'pass' in res:
'''''
判斷測(cè)試結(jié)果,然后把通過(guò)或者失敗插入到測(cè)試結(jié)果的list中
'''
res_flags.append('pass')
else:
res_flags.append('fail')
'''''
如果不通過(guò)的話,就調(diào)用寫bug的方法,把case_id、接口名稱、請(qǐng)求報(bào)文、返回報(bào)文和預(yù)期結(jié)果傳進(jìn)去
writeBug方法在下面定義了,具體實(shí)現(xiàn)是先連接數(shù)據(jù)庫(kù),然后拼sql,插入到bug表中
'''
writeBug(case_id,interface_name,new_url,results,res_check)
'''''
全部用例執(zhí)行完之后,會(huì)調(diào)用copy_excel方法,把測(cè)試結(jié)果寫到excel中,
每一條用例的請(qǐng)求報(bào)文、返回報(bào)文、測(cè)試結(jié)果,這三個(gè)每個(gè)我在上面都定義了一個(gè)list
來(lái)存每一條用例執(zhí)行的結(jié)果,把源excel用例的路徑和三個(gè)list傳進(jìn)去調(diào)用即可,copy_excel方
法在下面定義了,也加了注釋
'''
copy_excel(file_path,res_flags,request_urls,responses)
def readRes(res,res_check):
'''''
:param res: 返回報(bào)文
:param res_check: 預(yù)期結(jié)果
:return: 通過(guò)或者不通過(guò),不通過(guò)的話會(huì)把哪個(gè)參數(shù)和預(yù)期不一致返回
'''
'''''
返回報(bào)文的例子是這樣的{"id":"J_775682","p":275.00,"m":"458.00"}
excel預(yù)期結(jié)果中的格式是xx=11;xx=22這樣的,所以要把返回報(bào)文改成xx=22這樣的格式
所以用到字符串替換,把返回報(bào)文中的":"和":替換成=,返回報(bào)文就變成
{"id=J_775682","p=275.00,"m=458.00"},這樣就和預(yù)期結(jié)果一樣了,當(dāng)然也可以用python自帶的
json模塊來(lái)解析json串,但是有的返回的不是標(biāo)準(zhǔn)的json格式,處理起來(lái)比較麻煩,這里我就用字符串的方法了
'''
res = res.replace('":"',"=").replace('":',"=")
'''''
res_check是excel中的預(yù)期結(jié)果,是xx=11;xx=22這樣的
所以用split分割字符串,split是python內(nèi)置函數(shù),切割字符串,變成一個(gè)list
['xx=1','xx=2']這樣的,然后遍歷這個(gè)list,判斷l(xiāng)ist中的每個(gè)元素是否存在這個(gè)list中,
如果每個(gè)元素都在返回報(bào)文中的話,就說(shuō)明和預(yù)期結(jié)果一致
上面我們已經(jīng)把返回報(bào)文變成{"id=J_775682","p=275.00,"m=458.00"}
'''
res_check = res_check.split(';')
for s in res_check:
'''''
遍歷預(yù)期結(jié)果的list,如果在返回報(bào)文中,什么都不做,pass代表什么也不做,全部都存在的話,就返回pass
如果不在的話,就返回錯(cuò)誤信息和不一致的字段,因?yàn)閞es_check是從excel里面讀出來(lái)的
字符Unicode類型的的,python的字符串是str類型的,所以要用str方法強(qiáng)制類型轉(zhuǎn)換,轉(zhuǎn)換成string類型的
'''
if s in res:
pass
else:
return '錯(cuò)誤,返回參數(shù)和預(yù)期結(jié)果不一致'+str(s)
return 'pass'
def urlParam(param):
'''''
參數(shù)轉(zhuǎn)換,把參數(shù)轉(zhuǎn)換為'xx=11&xx=2這樣'
'''
return param.replace(';','&')
def copy_excel(file_path,res_flags,request_urls,responses):
'''''
:param file_path: 測(cè)試用例的路徑
:param res_flags: 測(cè)試結(jié)果的list
:param request_urls: 請(qǐng)求報(bào)文的list
:param responses: 返回報(bào)文的list
:return:
'''
'''''
這個(gè)函數(shù)的作用是寫excel,把請(qǐng)求報(bào)文、返回報(bào)文和測(cè)試結(jié)果寫到測(cè)試用例的excel中
因?yàn)閤lrd模塊只能讀excel,不能寫,所以用xlutils這個(gè)模塊,但是python中沒(méi)有一個(gè)模塊能
直接操作已經(jīng)寫好的excel,所以只能用xlutils模塊中的copy方法,copy一個(gè)新的excel,才能操作
'''
#打開原來(lái)的excel,獲取到這個(gè)book對(duì)象
book = xlrd.open_workbook(file_path)
#復(fù)制一個(gè)new_book
new_book = copy.copy(book)
#然后獲取到這個(gè)復(fù)制的excel的第一個(gè)sheet頁(yè)
sheet = new_book.get_sheet(0)
i = 1
for request_url,response,flag in zip(request_urls,responses,res_flags):
'''''
同時(shí)遍歷請(qǐng)求報(bào)文、返回報(bào)文和測(cè)試結(jié)果這3個(gè)大的list
然后把每一條case執(zhí)行結(jié)果寫到excel中,zip函數(shù)可以將多個(gè)list放在一起遍歷
因?yàn)榈谝恍惺潜眍^,所以從第二行開始寫,也就是索引位1的位置,i代表行
所以i賦值為1,然后每寫一條,然后i+1, i+=1同等于i=i+1
請(qǐng)求報(bào)文、返回報(bào)文、測(cè)試結(jié)果分別在excel的8、9、11列,列是固定的,所以就給寫死了
后面跟上要寫的值,因?yàn)閑xcel用的是Unicode字符編碼,所以前面帶個(gè)u表示用Unicode編碼
否則會(huì)有亂碼
'''
sheet.write(i,8,u'%s'%request_url)
sheet.write(i,9,u'%s'%response)
sheet.write(i,11,u'%s'%flag)
i+=1
#寫完之后在當(dāng)前目錄下(可以自己指定一個(gè)目錄)保存一個(gè)以當(dāng)前時(shí)間命名的測(cè)試結(jié)果,time.strftime()是格式化日期
new_book.save('%s_測(cè)試結(jié)果.xls'%time.strftime('%Y%m%d%H%M%S'))
def writeBug(bug_id,interface_name,request,response,res_check):
'''''
這個(gè)函數(shù)用來(lái)連接數(shù)據(jù)庫(kù),往bugfree數(shù)據(jù)中插入bug,拼sql,執(zhí)行sql即可
:param bug_id: bug序號(hào)
:param interface_name: 接口名稱
:param request: 請(qǐng)求報(bào)文
:param response: 返回報(bào)文
:param res_check: 預(yù)期結(jié)果
:return:
'''
bug_id = bug_id.encode('utf-8')
interface_name = interface_name.encode('utf-8')
res_check = res_check.encode('utf-8')
response = response.encode('utf-8')
request = request.encode('utf-8')
'''''
因?yàn)樯厦鎺讉€(gè)字符串是從excel里面讀出來(lái)的都是Unicode字符集編碼的,
python的字符串上面指定了utf-8編碼的,所以要把它的字符集改成utf-8,才能把sql拼起來(lái)
encode方法可以指定字符集
'''
#取當(dāng)前時(shí)間,作為提bug的時(shí)間
now = time.strftime("%Y-%m-%d %H:%M:%S")
#bug標(biāo)題用bug編號(hào)加上接口名稱然后加上_結(jié)果和預(yù)期不符,可以自己隨便定義要什么樣的bug標(biāo)題
bug_title = bug_id + '_' + interface_name + '_結(jié)果和預(yù)期不符'
#復(fù)現(xiàn)步驟就是請(qǐng)求報(bào)文+預(yù)期結(jié)果+返回報(bào)文
step = '[請(qǐng)求報(bào)文]<br />'+request+'<br/>'+'[預(yù)期結(jié)果]<br/>'+res_check+'<br/>'+'<br/>'+'[響應(yīng)報(bào)文]<br />'+'<br/>'+response
#拼sql,這里面的項(xiàng)目id,創(chuàng)建人,嚴(yán)重程度,指派給誰(shuí),都在sql里面寫死,使用的時(shí)候可以根據(jù)項(xiàng)目和接口
# 來(lái)判斷提bug的嚴(yán)重程度和提交給誰(shuí)
sql = "INSERT INTO `bf_bug_info` (`created_at`, `created_by`, `updated_at`, `updated_by`, `bug_status`, `assign_to`, `title`, `mail_to`, `repeat_step`, `lock_version`, `resolved_at`, `resolved_by`, `closed_at`, `closed_by`, `related_bug`, `related_case`, `related_result`, " \
"`productmodule_id`, `modified_by`, `solution`, `duplicate_id`, `product_id`, " \
"`reopen_count`, `priority`, `severity`) VALUES ('%s', '1', '%s', '1', 'Active', '1', '%s', '系統(tǒng)管理員', '%s', '1', NULL , NULL, NULL, NULL, '', '', '', NULL, " \
"'1', NULL, NULL, '1', '0', '1', '1');"%(now,now,bug_title,step)
#建立連接,使用MMySQLdb模塊的connect方法連接mysql,傳入賬號(hào)、密碼、數(shù)據(jù)庫(kù)、端口、ip和字符集
coon = MySQLdb.connect(user='root',passwd='123456',db='bugfree',port=3306,host='127.0.0.1',charset='utf8')
#建立游標(biāo)
cursor = coon.cursor()
#執(zhí)行sql
cursor.execute(sql)
#提交
coon.commit()
#關(guān)閉游標(biāo)
cursor.close()
#關(guān)閉連接
coon.close()
if __name__ == '__main__':
'''''
然后進(jìn)行調(diào)用,調(diào)用的時(shí)候需要傳入一個(gè)excel,調(diào)用方式是 python test.py test_case.xls
sys.argv[1]的意思是取傳入的第二個(gè)參數(shù),也就是索引是1的,
第一個(gè)是這個(gè)python文件的文件名,如果不傳入?yún)?shù)運(yùn)行的話,會(huì)提示錯(cuò)誤,如果正確的話,
會(huì)調(diào)用讀excel的程序,執(zhí)行用例,運(yùn)行完成后,會(huì)打印Done
'''
try:
filename = sys.argv[1]
except IndexError,e:
print 'Please enter a correct testcase! \n e.x: python gkk.py test_case.xls'
else:
readExcel(filename)
print 'Done!'
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 10個(gè)Python自動(dòng)化辦公的腳本分享
- Python自動(dòng)化辦公之文件整理腳本分享
- 五個(gè)方便好用的Python自動(dòng)化辦公腳本的實(shí)現(xiàn)
- 6個(gè)實(shí)用的Python自動(dòng)化腳本詳解
- 實(shí)用自動(dòng)化運(yùn)維Python腳本分享
- python實(shí)現(xiàn)自動(dòng)化腳本編寫
- 十個(gè)簡(jiǎn)單使用的Python自動(dòng)化腳本分享
- 教你在Excel中調(diào)用Python腳本實(shí)現(xiàn)數(shù)據(jù)自動(dòng)化處理的方法
- 八個(gè)超級(jí)好用的Python自動(dòng)化腳本(小結(jié))
- Python自動(dòng)化辦公中的應(yīng)用說(shuō)明和腳本示例
相關(guān)文章
對(duì)pytorch網(wǎng)絡(luò)層結(jié)構(gòu)的數(shù)組化詳解
今天小編就為大家分享一篇對(duì)pytorch網(wǎng)絡(luò)層結(jié)構(gòu)的數(shù)組化詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
Python?使用BeautifulSoup庫(kù)的方法
BeautifulSoup庫(kù)用于從HTML或XML文件中提取數(shù)據(jù),它可以自動(dòng)將復(fù)雜的HTML文檔轉(zhuǎn)換為樹形結(jié)構(gòu),并提供簡(jiǎn)單的方法來(lái)搜索文檔中的節(jié)點(diǎn),使得我們可以輕松地遍歷和修改HTML文檔的內(nèi)容,本文給大家介紹Python?使用BeautifulSoup庫(kù)的方法,感興趣的朋友一起看看吧2023-10-10
Python獲取網(wǎng)絡(luò)圖片和視頻的示例代碼
Python 是一種多用途語(yǔ)言,廣泛用于腳本編寫。我們可以編寫Python 腳本來(lái)自動(dòng)化日常事務(wù)。本文將用Python實(shí)現(xiàn)獲取Google圖片和YouTube視頻,需要的可以參考一下2022-03-03
Python子進(jìn)程中創(chuàng)建多線程的完整指南
在操作系統(tǒng)中,進(jìn)程是資源分配的基本單位,每個(gè)進(jìn)程都有獨(dú)立的內(nèi)存空間、文件描述符等系統(tǒng)資源,而線程是進(jìn)程內(nèi)的執(zhí)行單元,多個(gè)線程共享同一進(jìn)程的資源,本文給大家介紹了Python子進(jìn)程中創(chuàng)建多線程的完整指南,需要的朋友可以參考下2025-08-08
Python多線程處理實(shí)例詳解【單進(jìn)程/多進(jìn)程】
這篇文章主要介紹了Python多線程處理,結(jié)合實(shí)例形式總結(jié)分析了Python單進(jìn)程、多進(jìn)程、多線程等相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2019-01-01

