引言
很多人都知道,目前市場上很多自動化測試工具,比如:Jmeter,Postman,TestLink等,還有一些自動化測試平台,那為啥還要開發接口自動化測試框架呢?
相同之處就不說了,先說一下工具的局限性:
1.測試數據不可控:
接口雖然是對業務邏輯、程序代碼的測試,而實際上是對數據的測試,調用接口輸入一批數據,通過斷言代碼驗證接口返回的數據,整個過程圍繞數據測試。
如果返回的數據不是固定的,是變化的,那么斷言失敗,就無法知道是接口程序錯誤引起的,還是數據變化引起的,所以就需要進行測試數據初始化。
接口工具沒有具備數據初始化的功能,從而無法真正做到接口自動化測試。
舉個例子來幫助理解:
比如你要測試一個查詢接口,在沒有初始化測試數據的情況下,你入參是:id = 1,斷言是: assert name = ‘測試’, 這個斷言是你預先知道接口會返回什么。調用接口時候,接口返回結果是name = ‘測試’,斷言成功,因為你知道數據庫有一條id=1的數據。
哪天這條id=1的數據被人刪除,但是你維護的接口測試框架還在跑,並沒有更新測試數據,結果斷言失敗,你上去debug,最后發現是測試數據的問題,這個過程是費時又費勁的,
如果做了測試數據初始化的功能,完全是可以避免的。
因為入參和出參都是固定的,是按自己需要初始化好的,不用擔心數據變化引發斷言失敗,那么只關心接口程序代碼的問題了。
2.無法測試加密接口
公司項目中,大部分接口是不供外部調用,會使用用戶認證、簽名、加密等手段,提供接口的安全性。而一般的測試工具無法做到模擬和生成這些加密算法。
3.擴展能力不足
工具始終是工具,有一定的局限性,無法生成自定義測試報告,無法定制化發送郵件,持續集成和定時任務。
4.對業務的支持程度
工具對業務支持程序相對比較低,無法根據不同業務定制化開發,而自動化測試框架可以做到這點,對業務支持比較靈活。
框架設計思路
1.大致處理流程:

2.接口自動化測試框架處理過程:
- 首先編寫一份測試數據初始化的腳本,維護一批測試數據到數據庫,並且每次初始化前,清空原來的數據,這樣保證數據是最新和唯一的(避免重復)。
- 調用被測系統的接口,傳入參數,這個請求參數是字典,並且數據與數據庫數據(數據是初始化時插入)中一致。
- 系統接口會根據入參,向測試數據庫查詢。
- 查詢結果組裝成一定格式(dict、json)的數據,返回給測試框架。
- 測試框架斷言接口返回的數據,並生成測試結果(測試報告)。
框架結構

框架介紹:
各個目錄的作用:
- common/: 報告、日志等公共模塊存放文件夾
- config/: 文件路徑、配置信息存放
- db_init/: 測試數據初始化處理程序
- logs/: 生成日志文件
- pies/: 餅圖存放
- report/: 測試報告存放
- testcase/: 用於編寫測試用例
- run_main.py 執行測試集的主程序
主程序運行文件run_main.py:
# -*- coding: utf-8 -*-
'''
@author: liudinglong
@software: pycharm
@file: run_main.py
@time: 2020/2/23 0023 13:46
'''
import time ,sys
# 引用模塊路徑
sys.path.append('./testcase')
sys.path.append('./db_fixture')
from common.HTMLTestRunner3 import HTMLTestRunner
from unittest import defaultTestLoader
from db_init import data_init
# 指定測試用例為當前文件夾下的 interface 目錄
test_dir = './testcase'
# 自動獲取interface 目錄下的測試用例
testsuit = defaultTestLoader.discover(test_dir,pattern='*test.py')
if __name__ == '__main__':
# 初始化接口測試數據
data_init.init_data()
# 獲取當前時間
now = time.strftime("%Y-%m-%d %H_%M_%S")
# 定制報告名稱
filename = './report/' + now + '_result.html'
# 向報告寫入測試結果數據
fp = open(filename, 'wb')
runner = HTMLTestRunner(stream=fp,
title='接口自動化測試報告',
description='運行環境:環境:windows 10 瀏覽器:chrome 語言: Python3')
# 運行測試集
runner.run(testsuit)
# 關閉報告文件
fp.close()
測試數據初始化data_init.py:
# -*- coding: utf-8 -*-
'''
@author: liudinglong
@software: pycharm
@file: data_init.py
@time: 2020/2/23 0023 13:37
'''
import sys, time,datetime
sys.path.append('../db_init')
try:
from mysql_conn import DB
except ImportError:
from .mysql_conn import DB
# 定義過去時間,time.localtime(time.time())格式化時間戳為本地時間
past_time = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()-100000))
# 定義將來時間
future_time = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()+10000))
# 獲取當前時間
now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# create data
datas = {
'django_web_event':[
{'id':1,'name':'紅米Pro發布會','`limit`':2000,'status':1,'address':'北京會展中心','start_time':future_time},
{'id':2,'name':'可參加人數為0','`limit`':0,'status':1,'address':'北京會展中心','start_time':future_time},
{'id':3,'name':'當前狀態為0關閉','`limit`':2000,'status':0,'address':'北京會展中心','start_time':future_time},
{'id':4,'name':'發布會已結束','`limit`':2000,'status':1,'address':'北京會展中心','start_time':past_time},
{'id':5,'name':'小米5發布會','`limit`':2000,'status':1,'address':'北京國家會議中心','start_time':future_time},
],
'django_web_guest':[
{'id':1,'realname':'alen','phone':13511001100,'email':'alen@mail.com','sign':0,'event_id':1},
{'id':2,'realname':'has sign','phone':13511001101,'email':'sign@mail.com','sign':1,'event_id':1},
{'id':3,'realname':'tom','phone':13511001102,'email':'tom@mail.com','sign':0,'event_id':5},
],
}
# Inster table datas
def init_data():
DB().init_data(datas)
if __name__ == '__main__':
init_data()
運行程序
運行結果:
......FFFFFF................. Time Elapsed: 0:00:00.208256
測試日志:

測試報告:

有錯誤不要害怕,看看報錯信息,再修改一下,運行后:

總結
在測試之前,要准備測試環境,如果是正式環境的接口,有條件的話,建議獨立創建測試數據庫,避免對正式數據造成影響。可以在本地創建或在正式庫服務器是上創建db,本套僅作為項目測試環境使用。
在數據庫初始化時,連接測試環境的數據庫,將自己需要的測試數據初始化進去,每次程序執行的時候,都初始化一遍,這樣的作用防止數據與正式數據沖突,並且防止測試數據重復和累積在數據庫中。
附錄
更多干貨分享:加入測試開發交流QQ群:696400122,獲取源碼學習交流! 僅僅來白嫖的繞道~
微信公眾號:全棧測試開發日記,
CSDN地址:https://blog.csdn.net/liudinglong1989/article/details/104457379
