本文章轉(zhuǎn)載于搜狗測試
首先款熬,容小編我說一個(gè)很尖銳的問題:業(yè)界有很多接口自動化工具渠退,比如postman、jmeter设预、httpapi徙歼、soupUI等。為啥還要自己搞一套框架(造輪子)鳖枕?
由于在項(xiàng)目中遇到了以下幾個(gè)問題:
1魄梯、對返回的json需要進(jìn)行層級檢查
例如:檢查返回的json中date下第五個(gè)list中的image的值為ad。
2宾符、對失敗case的結(jié)果提示能夠一眼看出case失敗的具體原因酿秸。
例如:不是json?返回404魏烫?json層級解析失斃彼铡?json的key不存在哄褒?json的value不存在稀蟋?
3、后續(xù)想方便的擴(kuò)充功能呐赡,以適用不同的項(xiàng)目需求退客。
例如:支持jsonp返回的json解析,支持protobuf的解析等链嘀。
以上三個(gè)問題萌狂,用業(yè)界的通用框架都難以滿足需求,所以決定自己寫一套框架~
對于框架管闷,我們的考慮是這幾方面:
易用性——是否簡單上手
通用性——是否通用基本的http接口測試需求
可擴(kuò)展性——是否方便的擴(kuò)展功能
易讀性——測試結(jié)果是否很直接的知道失敗具體原因
我們的愿景是這樣的~
如何不寫代碼就可以做接口測試呢粥脚?
你要做的就是:
寫excel用例
寫excel用例
寫excel用例
重要的事情說三遍~~~
具體用例是什么樣的呢?
所以你要做的就是按照excel的字段說明寫用例即可~
框架功能
⊙增加可定義post請求和get請求方法包个,增加header支持
⊙增加返回結(jié)果的校驗(yàn)刷允,支持xml冤留、json及純文本的返回內(nèi)容檢查
⊙增加case可選擇性執(zhí)行,支持Y-正常case树灶、E-異常case纤怒、N-不執(zhí)行case
⊙對xml及json的返回,支持每條case指定key-value對的檢查天通,增加失敗原因的提示
⊙支持json層級檢查及l(fā)ist的檢查
⊙增強(qiáng)返回異常結(jié)果的檢查泊窘,例如空、非200返回像寒。
⊙增強(qiáng)對運(yùn)行結(jié)果的統(tǒng)計(jì)及提示烘豹,支持失敗發(fā)送郵件提醒。
⊙支持301诺祸、302跳轉(zhuǎn)
⊙支持執(zhí)行所有sheet頁的case
⊙支持關(guān)聯(lián)
具體框架是如何實(shí)現(xiàn)的呢携悯?且聽我娓娓道來~
咳咳~~~不想看代碼的同學(xué),請直接跳到結(jié)尾~
框架介紹:
具體的實(shí)現(xiàn)流程如下:
main.py:入口函數(shù)筷笨,指定case文件及sheet頁
ExcelPath=os.getcwd()+'/TestCaseDir/yuedu_Testcase.xlsx'
SheetName='ALL'#需要執(zhí)行的sheet頁名稱憔鬼,如果想執(zhí)行所有sheet頁,必須為大寫的ALL
server_case.excelobj=create_excel(ExcelPath,SheetName)
#跑case胃夏,如果有錯(cuò)誤發(fā)出郵件通知
if SheetName.upper() == 'ALL':
#執(zhí)行所有sheet頁的用例
Sheetnames = []
Sheetnames =server_case.excelobj.get_all_sheetname()
#print Sheetnames
for SheetName in Sheetnames:
SheetName =str(SheetName)
mailbody,count =run(SheetName)
Sendmail('caochengzhen@sogou-inc.com', mailbody,count, SheetName)
else:
#執(zhí)行指定sheet頁的用例
mailbody,count =run(SheetName)
Sendmail('caochengzhen@sogou-inc.com', mailbody,count, SheetName)
讀取用例采用com組件讀取excel的方式
采用這種方式的原因是:
Com組件操作是windows提供的轴或,理論上可以支持所有excel的操作,在這里用到了如果case執(zhí)行失敗仰禀,將對應(yīng)項(xiàng)標(biāo)紅底色的功能照雁。
支持excel和wps,只需要將com組件名稱修改即可悼瘾。
self.xlApp = win32com.client.Dispatch('Excel.Application')?? #MS:Excel?WPS:et
try:
self.book =self.xlApp.Workbooks.Open(sFile)
except:
print_error_info()
print "打開文件失敗"
exit()
發(fā)送請求統(tǒng)一維護(hù)在HTTPInvoke(url,requestUri)方法中
def HTTPInvoke(url,requestUri):
proto,rest=urllib.splittype(url)
host,rest=urllib.splithost(rest)
conn =httplib.HTTPConnection(host)
ifreqmethod.upper()=="GET":
print url
conn.request(reqmethod.upper(), url,headers=reqHeaders)
rsps = conn.getresponse()
if rsps.status==200:
data = rsps.read()
data = str(data)
conn.close()
return data
elif rsps.status==301 orrsps.status==302:
headerstr=rsps.getheaders()
for i in headerstr:
ifi[0].lower()=='location':
url = i[1]
proto,rest=urllib.splittype(url)
host,rest=urllib.splithost(rest)
conn =httplib.HTTPConnection(host)
conn.request('GET', url)
rsps =conn.getresponse()
ifrsps.status==200:
data =rsps.read()
data = str(data)
conn.close()
returndata
else:
data='[Response_Code_err]:'+str(rsps.status)
data = str(data)
return data
ifreqmethod.upper()=="POST":
print requestUri + '\t' + 'body=' +sArge
conn.request(reqmethod.upper(),requestUri,body=sArge,headers=reqHeaders)
rsps =conn.getresponse()
if rsps.status==200:
data = rsps.read()
data = str(data)
conn.close()
return data
elif rsps.status==301 orrsps.status==302:
headerstr=rsps.getheaders()
print headerstr
for i in headerstr:
ifi[0].lower()=='location':
url = i[1]
proto,rest=urllib.splittype(url)
host,rest=urllib.splithost(rest)
conn =httplib.HTTPConnection(host)
conn.request('GET', url)
rsps =conn.getresponse()
ifrsps.status==200:
data =rsps.read()
data =str(data)
conn.close()
return data
else:
data='[Response_Code_err]:'+str(rsps.status)
return data
通過這個(gè)函數(shù)可以處理post請求囊榜,get請求、302跳轉(zhuǎn)請求亥宿。
對返回結(jié)果的遍歷校驗(yàn):
ResString=HTTPInvoke(sInput,requesturi)???? #執(zhí)行調(diào)用
print ResString
#獲取返回碼并比較
#printResString,checkitem
#如果服務(wù)器返回碼不是200卸勺,直接報(bào)錯(cuò)。
ifResString.startswith('[Response_Code_err]'):
real_value=ResString
print real_value
ret1=check_result(excelobj, suiteid, caseid,real_value,excelobj.CheckVaule)
#寫測試結(jié)果
write_result(excelobj, suiteid, caseid, excelobj.resultCol, ret1)
continue
#判斷是使用xml還是json解析烫扼。
if ResString.find('xmlversion=')>0:
try:
real_value=et.fromstring(ResString).find(checkitem).text
ret1=check_result(excelobj, suiteid, caseid,real_value,excelobj.CheckVaule)
except:
printsInput+"返回不是標(biāo)準(zhǔn)的XML曙求!"
real_value=sInput+"返回不是標(biāo)準(zhǔn)的XML!"
ret1=check_result(excelobj, suiteid, caseid,real_value,excelobj.CheckVaule)
elifResString.startswith('{'):
try:
ResString=ToUnicode(ResString)
hjson =json.loads(ResString)
expstr=excelobj.read_data(suiteid,excelobj.casebegin+caseid, 13)
ifstr(checkitem).startswith('['):
try:
checkitem= checkitem.replace("‘","'")
checkitem= checkitem.replace("’","'")
hjson =json.loads(ResString)
precmd='hjson'+checkitem
real_value=eval(precmd)
ret1=check_result(excelobj, suiteid, caseid,real_value,excelobj.CheckVaule)
except:
real_value=checkitem+'解析失敗映企,請檢查層級及語法悟狱!'
ret1=check_result(excelobj, suiteid, caseid,real_value,excelobj.CheckVaule)
else :
ResString=ToUnicode(ResString)
#printResString
ifResString.find(checkitem)>0:
pattern? =? re.compile(r'%s(.*?),' % checkitem)
res = pattern.findall(ResString)
ifres==[]:#如果要匹配的字段在最后,則沒有逗號堰氓,只能匹配大括號
pattern? =? re.compile(r'%s(.*?)}' % checkitem)
res =pattern.findall(ResString)
#printres[0]
else:
print'key:'+checkitem+'在response中不存在挤渐!'
real_value='key:'+checkitem+'在response中不存在!'
ret1=check_result(excelobj, suiteid, caseid,real_value,excelobj.CheckVaule)
#寫測試結(jié)果
write_result(excelobj, suiteid, caseid, excelobj.resultCol, ret1)
continue
real_value=res[0].replace('"','')
#printreal_value
real_value=real_value[1:]
ret1=check_result(excelobj, suiteid, caseid,real_value,excelobj.CheckVaule)
except:
printsInput+"返回不是標(biāo)準(zhǔn)的json双絮!"
real_value=sInput+"返回不是標(biāo)準(zhǔn)的json浴麻!"
ret1=check_result(excelobj, suiteid, caseid,real_value,excelobj.CheckVaule)
else:#非json非xml文件
expstr=excelobj.read_data(suiteid,excelobj.casebegin+caseid, 14)
ifResString.find(expstr)>0:
real_value=expstr
ret1=check_result(excelobj, suiteid, caseid,real_value,excelobj.CheckVaule)
else:
print sInput+'中不存在'+expstr
real_value=sInput+'中不存在'+expstr
ret1=check_result(excelobj, suiteid, caseid,real_value,excelobj.CheckVaule)
依次會校驗(yàn)錯(cuò)誤返回碼→xml→json→字符串進(jìn)行校驗(yàn)得问。
對于錯(cuò)誤的結(jié)果,發(fā)送郵件
mail_from = 'venus@sogou-inc.com'
mail_to = maillist
timenow = datetime.datetime.utcnow() + datetime.timedelta(hours=8)#東8區(qū)增加8小時(shí)
title = '【'+interfacename + '_接口測試結(jié)果】'+ timenow.strftime( '%Y-%m-%d %H:%M:%S' )
body = strHtml
if count[1] == 0:
print 'All Case is OK!'
pass
else:
sendEmail.SendMail(mail_from,mail_to, title, body)