本文經過從Postman獲取基本的接口測試Code簡單的接口測試入手,一步步調整優化接口調用,以及增長基本的結果判斷,講解Python自帶的Unittest框架調用,指望各位能夠經過本文對接口自動化測試有一個大體的了解。python
在當前互聯網產品迭代頻繁的背景下,迴歸測試的時間愈來愈少,很難在每一個迭代都對全部功能作完整迴歸。但接口自動化測試因其實現簡單、維護成本低,容易提升覆蓋率等特色,愈來愈受重視。json
使用Postman調試經過過直接能夠獲取接口測試的基本代碼,結合使用requets + unittest很容易實現接口自動化測試的封裝,並且requests的api已經很是人性化,很是簡單,但經過封裝之後(特別是針對公司內特定接口),能夠進一步提升腳本編寫效率。api
下面使用requests + unittest測試一個查詢接口markdown
請求信息:app
Method:POST框架
URL:api/match/image/getjson模塊化
Request:post
{ "category": "image", "offset": "0", "limit": "30", "sourceId": "0", "metaTitle": "", "metaId": "0", "classify": "unclassify", "startTime": "", "endTime": "", "createStart": "", "createEnd": "", "sourceType": "", "isTracking": "true", "metaGroup": "", "companyId": "0", "lastDays": "1", "author": "" }
Response示例:單元測試
{ "timestamp" : xxx, "errorMsg" : "", "data" : { "config" : xxx }
Postman測試方法見截圖:測試
1.獲取Postman原始腳本
2.使用requests庫模擬發送HTTP請求**
3.對原始腳本進行基礎改造**
4.使用python標準庫里unittest寫測試case**
該代碼只是簡單的一次調用,並且返回的結果太多,不少返回信息暫時沒用,示例代碼以下
import requests url = "http://cpright.xinhua-news.cn/api/match/image/getjson" querystring = {"category":"image","offset":"0","limit":"30","sourceId":"0","metaTitle":"","metaId":"0","classify":"unclassify","startTime":"","endTime":"","createStart":"","createEnd":"","sourceType":"","isTracking":"true","metaGroup":"","companyId":"0","lastDays":"1","author":""} headers = { 'cache-control': "no-cache", 'postman-token': "e97a99b0-424b-b2a5-7602-22cd50223c15" } response = requests.request("POST", url, headers=headers, params=querystring) print(response.text)
調整代碼結構,輸出結果Json出來,獲取須要驗證的response.status_code,以及獲取結果校驗須要用到的results['total']
#!/usr/bin/env python #coding: utf-8 ''' unittest merchant backgroud interface @author: zhang_jin @version: 1.0 @see:http://www.python-requests.org/en/master/ ''' import unittest import json import traceback import requests url = "http://cpright.xinhua-news.cn/api/match/image/getjson" querystring = { "category": "image", "offset": "0", "limit": "30", "sourceId": "0", "metaTitle": "", "metaId": "0", "classify": "unclassify", "startTime": "", "endTime": "", "createStart": "", "createEnd": "", "sourceType": "", "isTracking": "true", "metaGroup": "", "companyId": "0", "lastDays": "1", "author": "" } headers = { 'cache-control': "no-cache", 'postman-token': "e97a99b0-424b-b2a5-7602-22cd50223c15" } #Post接口調用 response = requests.request("POST", url, headers=headers, params=querystring) #對返回結果進行轉義成json串 results = json.loads(response.text) #獲取http請求的status_code print "Http code:",response.status_code #獲取結果中的total的值 print results['total'] #print(response.text)
接口調用異常處理,增長try,except處理,對於返回response.status_code,返回200進行結果比對,不是200數據異常信息。
#!/usr/bin/env python #coding: utf-8 ''' unittest merchant backgroud interface @author: zhang_jin @version: 1.0 @see:http://www.python-requests.org/en/master/ ''' import json import traceback import requests url = "http://cpright.xinhua-news.cn/api/match/image/getjson" querystring = { "category": "image", "offset": "0", "limit": "30", "sourceId": "0", "metaTitle": "", "metaId": "0", "classify": "unclassify", "startTime": "", "endTime": "", "createStart": "", "createEnd": "", "sourceType": "", "isTracking": "true", "metaGroup": "", "companyId": "0", "lastDays": "1", "author": "" } headers = { 'cache-control': "no-cache", 'postman-token': "e97a99b0-424b-b2a5-7602-22cd50223c15" } try: #Post接口調用 response = requests.request("POST", url, headers=headers, params=querystring) #對http返回值進行判斷,對於200作基本校驗 if response.status_code == 200: results = json.loads(response.text) if results['total'] == 191: print "Success" else: print "Fail" print results['total'] else: #對於http返回非200的code,輸出相應的code raise Exception("http error info:%s" %response.status_code) except: traceback.print_exc()
1.該版本改動較大,引入config文件,單獨封裝結果校驗模塊,引入unittest模塊,實現接口自動調用,並增長log處理模塊;
2.對不一樣Post請求結果進行封裝,不一樣接口分開調用;
3.測試用例的結果進行統計並最終輸出
#!/usr/bin/env python #coding: utf-8 ''' unittest interface @author: zhang_jin @version: 1.0 @see:http://www.python-requests.org/en/master/ ''' import unittest import json import traceback import requests import time import result_statistics import config as cf from com_logger import match_Logger class MyTestSuite(unittest.TestCase): """docstring for MyTestSuite""" #@classmethod def sedUp(self): print "start..." #圖片匹配統計 def test_image_match_001(self): url = cf.URL1 querystring = { "category": "image", "offset": "0", "limit": "30", "sourceId": "0", "metaTitle": "", "metaId": "0", "classify": "unclassify", "startTime": "", "endTime": "", "createStart": "", "createEnd": "", "sourceType": "", "isTracking": "true", "metaGroup": "", "companyId": "0", "lastDays": "1", "author": "" } headers = { 'cache-control': "no-cache", 'postman-token': "545a2e40-b120-2096-960c-54875be347be" } response = requests.request("POST", url, headers=headers, params=querystring) if response.status_code == 200: response.encoding = response.apparent_encoding results = json.loads(response.text) #預期結果與實際結果校驗,調用result_statistics模塊 result_statistics.test_result(results,196) else: print "http error info:%s" %response.status_code #match_Logger.info("start image_query22222") #self.assertEqual(results['total'], 888) ''' try: self.assertEqual(results['total'], 888) except: match_Logger.error(traceback.format_exc()) #print results['total'] ''' #文字匹配數據統計 def test_text_match_001(self): text_url = cf.URL2 querystring = { "category": "text", "offset": "0", "limit": "30", "sourceId": "0", "metaTitle": "", "metaId": "0", "startTime": "2017-04-14", "endTime": "2017-04-15", "createStart": "", "createEnd": "", "sourceType": "", "isTracking": "true", "metaGroup": "", "companyId": "0", "lastDays": "0", "author": "", "content": "" } headers = { 'cache-control': "no-cache", 'postman-token': "ef3c29d8-1c88-062a-76d9-f2fbebf2536c" } response = requests.request("POST", text_url, headers=headers, params=querystring) if response.status_code == 200: response.encoding = response.apparent_encoding results = json.loads(response.text) #預期結果與實際結果校驗,調用result_statistics模塊 result_statistics.test_result(results,190) else: print "http error info:%s" %response.status_code #print(response.text) def tearDown(self): pass if __name__ == '__main__': #image_match_Logger = ALogger('image_match', log_level='INFO') #構造測試集合 suite=unittest.TestSuite() suite.addTest(MyTestSuite("test_image_match_001")) suite.addTest(MyTestSuite("test_text_match_001")) #執行測試 runner = unittest.TextTestRunner() runner.run(suite) print "success case:",result_statistics.num_success print "fail case:",result_statistics.num_fail #unittest.main()
Zj-Mac:unittest lazybone$ python image_test_3.py
測試結果:經過
.測試結果:不經過
錯誤信息: 指望返回值:190 實際返回值:4522 . ---------------------------------------------------------------------- Ran 2 tests in 0.889s OK success case: 1 fail case: 1
1.unittest輸出報告也能夠推薦使用HTMLTestRunner(我目前是對結果統計進行了封裝)
2.接口的繼續封裝,參數化,模塊化
3.unittest單元測試框架實現參數化調用第三方模塊引用(nose-parameterized)
4.持續集成運行環境、定時任務、觸發運行、郵件發送等一系列功能都可以在Jenkins上實現。