1. 什么是接口測試
顧名思義,接口測試是對系統或組件之間的接口進行測試,主要是校驗數據的交換,傳遞和控制管理過程,以及相互邏輯依賴關系。其中接口協議分為HTTP,WebService,Dubbo,Thrift,Socket等類型,測試類型又主要分為功能測試,性能測試,穩定性測試,安全性測試等。
在分層測試的“金字塔”模型中,接口測試屬於第二層服務集成測試范疇。相比UI層(主要是WEB或APP)自動化測試而言,接口自動化測試收益更大,且容易實現,維護成本低,有着更高的投入產出比,是每個公司開展自動化測試的首選。
下面我們以一個HTTP接口為例,完整的介紹接口自動化測試流程:從需求分析到用例設計,從腳本編寫、測試執行到結果分析,並提供完整的用例設計及測試腳本。
2. 基本流程
基本的接口功能自動化測試流程如下:
需求分析 -> 用例設計 -> 腳本開發 -> 測試執行 -> 結果分析
2.1 示例接口
接口名稱:豆瓣電影搜索
接口文檔地址:https://developers.douban.com/wiki/?title=movie_v2#search
接口調用示例:
1) 按演職人員搜索:https://api.douban.com/v2/movie/search?q=張藝謀
2) 按片名搜索:https://api.douban.com/v2/movie/search?q=大話西游
3) 按類型搜索:https://api.douban.com/v2/movie/search?tag=喜劇
3. 需求分析
需求分析是參考需求、設計等文檔,在了解需求的基礎上還需清楚內部的實現邏輯,並且可以在這一階段提出需求、設計存在的不合理或遺漏之處。
如:豆瓣電影搜索接口,我理解的需求即是支持對片名,演職人員及標簽的搜索,並分頁返回搜索結果。
4. 用例設計
用例設計是在理解接口測試需求的基礎上,使用MindManager或XMind等思維導圖軟件編寫測試用例設計,主要內容包括參數校驗,功能校驗、業務場景校驗、安全性及性能校驗等,常用的用例設計方法有等價類划分法,邊界值分析法,場景分析法,因果圖,正交表等。
針對豆瓣電影搜索接口功能測試部分,我們主要從參數校驗,功能校驗,業務場景校驗三方面,設計測試用例如下:
5. 腳本開發
依據上面編寫的測試用例設計,我們使用python+nosetests框架編寫了相關自動化測試腳本。可以完整實現接口自動化測試、自動執行及郵件發送測試報告功能。
5.1 相關lib安裝
必要的lib庫如下,使用pip命令安裝即可:
pip install nose
pip install nose-htmloutput
pip install requests
5.2 接口調用
使用requests庫,我們可以很方便的編寫上述接口調用方法(如搜索q=劉德華,示例代碼如下):
#coding=utf-8
import requests
import json
url = 'https://api.douban.com/v2/movie/search'
params=dict(q=u'劉德華')
r = requests.get(url, params=params)
print 'Search Params:\n', json.dumps(params, ensure_ascii=False)
print 'Search Response:\n', json.dumps(r.json(), ensure_ascii=False, indent=4)
在實際編寫自動化測試腳本時,我們需要進行一些封裝。如下代碼中我們對豆瓣電影搜索接口進行了封裝,test_q方法只需使用nosetests提供的yield方法即可很方便的循環執行列表qs中每一個測試集:
class test_doubanSearch(object):
@staticmethod
def search(params, expectNum=None):
url = 'https://api.douban.com/v2/movie/search'
r = requests.get(url, params=params)
print 'Search Params:\n', json.dumps(params, ensure_ascii=False)
print 'Search Response:\n', json.dumps(r.json(), ensure_ascii=False, indent=4)
def test_q(self):
# 校驗搜索條件 q
qs = [u'白夜追凶', u'大話西游', u'周星馳', u'張藝謀', u'周星馳,吳孟達', u'張藝謀,鞏俐', u'周星馳,大話西游', u'白夜追凶,潘粵明']
for q in qs:
params = dict(q=q)
f = partial(test_doubanSearch.search, params)
f.description = json.dumps(params, ensure_ascii=False).encode('utf-8')
yield (f,)
我們按照測試用例設計,依次編寫每個功能的自動化測試腳本即可。
5.3 結果校驗
在手工測試接口的時候,我們需要通過接口返回的結果判斷本次測試是否通過,自動化測試也是如此。
對於本次的接口,我們搜索“q=劉德華”,我們需要判斷返回的結果中是否含有“演職人員劉德華或片名劉德華”,搜索“tag=喜劇”時,需要判斷返回的結果中電影類型是否為“喜劇”,結果分頁時需要校驗返回的結果數是否正確等。完整結果校驗代碼如下:
class check_response():
@staticmethod
def check_result(response, params, expectNum=None):
# 由於搜索結果存在模糊匹配的情況,這里簡單處理只校驗第一個返回結果的正確性
if expectNum is not None:
# 期望結果數目不為None時,只判斷返回結果數目
eq_(expectNum, len(response['subjects']), '{0}!={1}'.format(expectNum, len(response['subjects'])))
else:
if not response['subjects']:
# 結果為空,直接返回失敗
assert False
else:
# 結果不為空,校驗第一個結果
subject = response['subjects'][0]
# 先校驗搜索條件tag
if params.get('tag'):
for word in params['tag'].split(','):
genres = subject['genres']
ok_(word in genres, 'Check {0} failed!'.format(word.encode('utf-8')))
# 再校驗搜索條件q
elif params.get('q'):
# 依次判斷片名,導演或演員中是否含有搜索詞,任意一個含有則返回成功
for word in params['q'].split(','):
title = [subject['title']]
casts = [i['name'] for i in subject['casts']]
directors = [i['name'] for i in subject['directors']]
total = title + casts + directors
ok_(any(word.lower() in i.lower() for i in total),
'Check {0} failed!'

