1.什么是接口自動化測試
1.1概念
接口測試:是對系統之間或組件之間的接口進行測試,主要是校驗數據的交換、傳遞和控制管理過程,以及相互的邏輯依賴關系。
自動化測試:是把以人為驅動的測試行為轉化為機器執行的一種過程。
接口自動化測試:是讓程序或工具代替人工自動完成對進行測試的這一過程。
1.2實現方式
-
使用接口測試工具來實現,比如 JMeter、postman
-
通過編寫代碼來實現
1.3接口測試工具的不足(本文主要推崇以程序實現自動化測試)
-
測試數據不好控制(工具中無法直接讀取json格式數據)
- 不方便測試加密接口
- 擴展能力不足(復雜業務邏輯、復雜斷言)
2.Requests庫是什么?
2.1介紹
2.2安裝
pip install requests
3.接口請求方式
3.1GET請求
無參數版
含參數版
3.2POST請求
參數格式為json
參數json與data的區別
python中的字典與json格式的數據,雖然外表沒區別,但是數據序列化不一樣;所以可以將字典通過json模塊轉成json字符串,再傳到后台
響應數據.text和響應數據.json()的區別
3.3put請求方式
3.4delete請求方式
3.5響應方法
4.案例1
需求
案例實現分析
5.基於Unittest框架接口自動化
5.1結構
class TestData(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def test_login_success(self): pass def test_username_not_exist(self): pass def test_password_error(self): pass
5.2古詩詞網的自動化測試
雲打碼破解驗證碼
import http.client, mimetypes, urllib, json, time, requests ###################################################################### class YDMHttp: apiurl = 'http://api.yundama.com/api.php' username = '' password = '' appid = '' appkey = '' def __init__(self, username, password, appid, appkey): self.username = username self.password = password self.appid = str(appid) self.appkey = appkey def request(self, fields, files=[]): response = self.post_url(self.apiurl, fields, files) response = json.loads(response) return response def balance(self): data = {'method': 'balance', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey} response = self.request(data) if (response): if (response['ret'] and response['ret'] < 0): return response['ret'] else: return response['balance'] else: return -9001 def login(self): data = {'method': 'login', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey} response = self.request(data) if (response): if (response['ret'] and response['ret'] < 0): return response['ret'] else: return response['uid'] else: return -9001 def upload(self, filename, codetype, timeout): data = {'method': 'upload', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'codetype': str(codetype), 'timeout': str(timeout)} file = {'file': filename} response = self.request(data, file) if (response): if (response['ret'] and response['ret'] < 0): return response['ret'] else: return response['cid'] else: return -9001 def result(self, cid): data = {'method': 'result', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'cid': str(cid)} response = self.request(data) return response and response['text'] or '' def decode(self, filename, codetype, timeout): cid = self.upload(filename, codetype, timeout) if (cid > 0): for i in range(0, timeout): result = self.result(cid) if (result != ''): return cid, result else: time.sleep(1) return -3003, '' else: return cid, '' def report(self, cid): data = {'method': 'report', 'username': self.username, 'password': self.password, 'appid': self.appid, 'appkey': self.appkey, 'cid': str(cid), 'flag': '0'} response = self.request(data) if (response): return response['ret'] else: return -9001 def post_url(self, url, fields, files=[]): for key in files: files[key] = open(files[key], 'rb'); res = requests.post(url, files=files, data=fields) return res.text def getcode(username, pwd, codepath, codetype): # 用戶名(普通用戶) username = username # 密碼 password = pwd # 軟件ID,開發者分成必要參數。登錄開發者后台【我的軟件】獲得! appid = 9360 # 軟件密鑰,開發者分成必要參數。登錄開發者后台【我的軟件】獲得! appkey = 'f4a739c9df9c63dfa7461bdb083a8a25' # 圖片文件 filename = codepath # 驗證碼類型,# 例:1004表示4位字母數字,不同類型收費不同。請准確填寫,否則影響識別率。在此查詢所有類型 http://www.yundama.com/price.html codetype = codetype # 超時時間,秒 timeout = 30 result = None # 檢查 if (username == 'username'): print('請設置好相關參數再測試') else: # 初始化 yun_da_ma = YDMHttp(username, password, appid, appkey) # 登陸雲打碼 uid = yun_da_ma.login() print('uid: %s' % uid) # 查詢余額 balance = yun_da_ma.balance() print('balance: %s' % balance) # 開始識別,圖片路徑,驗證碼類型ID,超時時間(秒),識別結果 cid, result = yun_da_ma.decode(filename, codetype, timeout) print('cid: %s, result: %s' % (cid, result)) return result
自動化測試古詩詞網
import unittest import requests # 我們可能還會希望生成一個簡單的HTML報告,可使用HTMLTestRunner實現。但pypi和官網上最新的都是只支持 # python2.x的0.8.2版本。可將以下代碼自行保存成HTMLTestRunner.py放到自己項目目錄下 import HTMLTestRunner from lxml import etree from yunda import getcode # 新建測試類 class TestData(unittest.TestCase): def setUp(self): # 獲取session對象 self.session = requests.Session() # 登錄url self.login_url = "https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx" page_text = requests.get(url=self.login_url).text tree = etree.HTML(page_text) # 驗證碼圖片的url self.img_url = 'https://so.gushiwen.org' + tree.xpath('//*[@id="imgCode"]/@src')[0] def tearDown(self): # 關閉session self.session.close() def test_login_success(self): # 使用session獲取驗證碼的cookies信息 self.session.get(url=self.img_url) # 請求登錄 data = { "__VIEWSTATE": "9AsGvh3Je/0pfxId7DYRUi258ayuEG4rrQ1Z3abBgLoDSOeAUatOZOrAIxudqiOauXpR9Zq+dmKJ28+AGjXYHaCZJTTtGgrEemBWI1ed7oS7kpB7Rm/4yma/+9Q=", "__VIEWSTATEGENERATOR": "C93BE1AE", "from": "http://so.gushiwen.org/user/collect.aspx", "email": "1786887****", "pwd": "******", "code": getcode('****', 'yun25****', './img.jpg', 1004), "denglu": "登錄" } r = self.session.post(url=self.login_url, data=data) try: # 斷言 self.assertEqual(200, r.status_code) print("success login ") except AssertionError as e: print("登錄出錯:", e) def test_username_not_exist(self): pass def test_password_error(self): pass if __name__ == "__main__": suite = unittest.TestSuite() # TestData是要測試的類名,test_two是要執行的測試方法 suite.addTest(TestData("test_login_success")) suite.addTest(TestData("test_username_not_exist")) # runner = unittest.TextTestRunner() # runner.run(suite) filename = 'h:\\gu_shi_wen_wang.html' fb = open(filename, 'wb') runner = HTMLTestRunner.HTMLTestRunner(stream=fb,verbosity=2, title="測試HTMLTestRunner", description="測試HTMLTestRunner") runner.run(suite) fb.close()