目錄
Python接口測試課程(第一天)-Python基礎
Python接口測試課程(第二天)-接口測試快速實踐
Python接口測試課程(第三天)-接口安全驗證,參數化及斷言
Python接口測試課程(第四天)-接口測試框架實現
PDF下載:鏈接:https://pan.baidu.com/s/1x3_LYq23F_1LviGVbRNFXw 密碼:xrcj
更多學習資料請加添加作者微信:superz-han 獲取
第二天: Python接口測試(一)
簡單接口搭建(表單/REST)
五步教會你寫接口
首先要安裝flask包:
pip install flask
- 從flask中導入Flask類和request對象:
from flask import Flask, request
- 從當前模塊實例化出一個Flask實例:
app=Flask(__name__)
- 編寫一個函數來處理請求
- 從請求對象中獲取數據:
a=request.values.get("a");b=request.values.get("b")
- request.params: 字典格式,存儲請求中的url參數
- request.form: 字典格式,存儲請求中的表單數據
- request.values: 字典格式, 包含params和form中的值
- request.json: 字典格式, 存儲json類型的請求數據, 如果請求類型非json, 值為空
- 進行業務處理:
sum = int(a) + int(b)
- 組裝並返回響應數據:
return str(sum) # http一般使用字符串傳輸數據
- 從請求對象中獲取數據:
- 為接口指定接口地址和接受的方法:
@app.route("/add/", methods=["GET"]) # 寫到函數上面(裝飾器)
- 運行接口:
- 最后添加:
if __name__ == "__main__":
app.run()
2. 保存為```add.py```, 打開命令行,進入add.py所在目錄,運行```python add.py```ß
完整代碼
# 1. 導入包
from flask import Flask, request
# 2. 實例化一個
app = Flask(__name__)
# 3. 編寫一個接口處理方法
@app.route("/add/", methods=["GET","POST"]) # 4. 掛載路由(指定接口的url路徑), 聲明接口接受的方法
def add():
# 3.1 從請求中獲取參數
# request.values {"a": "1", "b": "2"}
a = request.values.get("a")
b = request.values.get("b")
# 3.2 業務操作
sum = int(a) + int(b)
# 3.3 組裝響應並返回
return str(sum)
# 5. 運行接口
if __name__ == '__main__':
app.run() # 默認5000端口,可以指定端口app.run(port=50001)
REST類型接口實現
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/api/sub/", methods=["POST"])
def sub():
if not request.json: # 如果請求數據類型非json
return jsonify({"code": "100001", "msg": "請求類型錯誤", "data": None})
if not "a" in request.json or not "b" in request.json: # 如果參數中沒有a或者沒有b
return jsonify({"code": "100002", "msg": "參數缺失", "data": None})
a = request.json.get("a")
b = request.json.get("b")
result = str(float(a) - float(b)) # 使用float支持浮點數相減
return jsonify({"code": "100000", "msg": "成功", "data": result}) # 使用jsonify將字典數據轉換為json類型的相應數據
if __name__ == '__main__':
app.run()
使用Postman測試接口(Form/Json)
編寫接口文檔
接口測試基礎
接口測試概念
接口測試是測試系統組件間接口的一種測試。
接口測試主要用於檢測外部系統與系統之 間以及內部各個子系統之間的交互點。測試的重點是要檢查數據的交換,傳遞和控制管理過 程,以及系統間的相互邏輯依賴關系等。
接口測試目的
- 核心:保證系統的穩定
- 手段:持續集成
- 目的:提高測試效率,提升用戶體驗,降低產品研發成本
接口測試一般流程
- 列出需求
- 安排資源,編寫接口用例 -> 用例評審
- 編寫接口測試代碼 -> 代碼評審codeReview
- 執行接口測試
接口測試關注點
- 功能:功能實現,實現與設計一致, 接口通過性測試
- 健壯性: 邊界值,容錯性
- 性能: 並發及壓測
- 穩定性: 長期運行的穩定性
- 安全性: SQL注入, session依賴, 數字簽名, http接口的安全性
常見接口種類
- Http/Https接口: 通過http/https協議傳送接口數據(通常按字符串/二進制傳輸), 如常見的網頁表單, https安全性更好
- RESTful Api: REST表述性狀態傳遞. 一種設計風格,基於http/https協議, 把一切接口視為資源, 接口要分版本,在統一的域名下管理, 不同的方法(get/post..)做不同的事,通常請求及響應使用json格式
- Web Service: SOAP簡單面向對象協議, 基於http實現的一種RPC方案.接口返回一些對象,可以直接通過操作對象,實現我們需要的業務處理.使用xml格式傳輸數據
- RPC接口: RPC為遠程方法調用, 有不同的實現方案,基於TCP/Http協議的都有. RPC可以想我們本地導入和調用對象一樣使用. Dubbo接口也是一種RPC接口.
常見接口數據類型
- 請求數據類型(Content-Type):
- application/x-www-form-urlencoded: 常規只有文本的網頁表單
- application/json: RESTful Api常用格式, 結構清晰, 含有多層嵌套
- multipart/form-data: 既有文本,又有上傳文件或富文本框的混合數據表單
- text/xml: xml格式, RPC接口常用格式
- 響應數據類型
- string/html: 返回字符串或網頁源碼
- json: RESTful Api常用響應格式, 結構清晰
- xml: RPC接口常用格式
常見接口安全驗證方式
- Auth_1.0/Auth_2.0: 通用接口授權方式
- Session依賴: 需要登錄之后才能進行接口操作
- Token驗證: 先要使用自己的appid/appsecret通過獲取token接口驗證身份獲取一個token(令牌,有一定有效期), 然后帶着token訪問接口
- 數字簽名: 將原本的參數按一定規則進行組合,配合時間戳或appsecret, 通過加密算法生成一個簽名sign, 攜帶簽名進行接口請求
常見接口請求方法
- GET: 獲取資源
- POST: 修改資源
- PUT: 上傳資源
- DELETE: 刪除資源
- HEAD: 只請求頁面首部
- PATCH: 補丁
- OPTIONS: 運行客戶端查看服務器性能
......
常見狀態碼(RESTful規范)
- 200系: 成功
- 200 OK - [GET]:獲取資源成功
- 201 CREATED - [POST/PUT/PATCH]:創建/修改成功
- 202 Accepted - [*]:任務接受
- 204 NO CONTENT - [DELETE]:刪除成功
- 300系: 重定向
- 301 Moved Permanently: 永久重定向
- 302 Found: 臨時重定向
- 400: 資源錯誤
- 400 INVALID REQUEST - [POST/PUT/PATCH]:用戶請求錯誤
- 401 Unauthorized - [*]:沒有權限(鑒權失敗, 接口層)
- 403 Forbidden - [*] 資源禁止訪問(服務器層,沒有訪問權限)
- 404 NOT FOUND - [*]:資源不存在
- 405 Method Not Allowd: 訪問的方法不允許, 如用POST訪問只支持GET請求的接口
- 406 Not Acceptable - [GET]:用戶請求的格式不可得(比如用戶請求JSON格式,但是只有XML格式)
- 410 Gone -[GET]:資源被永久刪除
- 422 Unprocesable entity - [POST/PUT/PATCH] 當創建對象時,發生驗證錯誤
- 500系: 服務器內部錯誤(接口崩潰或有Bug)
- 500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤
接口業務類型
- 返回數據型接口: 只從數據庫讀取數據
- 業務操作型接口: 需要寫數據庫(接口測試需要要涉及參數化或環境清理)
快速上手接口測試
獲取接口文檔
- Wiki
- Word文檔
- Postman導出
- 抽象接口定義
- 接口管理平台
接口文檔分析
- 功能分析: 是否能滿足業務(是否缺少某個前端需要的參數), 是否能滿足所有業務場景(是否有漏開發接口, 比如只開發了單品接口,沒開發套餐接口)
- 設計分析: 是否有不規范字段(如,nickname, passwd);不規范格式(如sex,用男,女而不是1,2);是否有易混淆字段(如amount和total);是否有單詞拼錯;是否有和數據庫字段對應但名稱不一樣的(易錯)
- 接口分析: 協議類型(http要考慮安全);請求方法(是否規范);請求編碼格式(表單/Json/xml, 很多接口文檔不聲明,導致測試調試不通);接口授權方式;接口業務類型(關系到是否需要做參數化或環境清理); 返回值類型及結構(關系到怎么斷言)
- 接口依賴: 需要什么環境准備和業務場景, 依賴那些接口, 有那些動態數據, 預備環境怎么保障
- 參數分析: 各個參數的參數類型,組成規則,是否允許不傳,是否可以為空, 是否允許多傳參
- 業務分析: 如price字段必須和數據庫中的商品的price字段一致,才能校驗通過
- 非功能性: 接口的技術實現方案是否合理, 能否滿足高並發的性能要求, 邊界值/極限值的處理是否合適, 是否前后端都有數據格式校驗等(如精確度為秒級的訂單號生成器,在高並發下會導致生成同一訂單號的問題)
- 其他: 如反爬,對headers的一些限制和校驗, ip等限制
編寫接口用例
Excel/TestLink/禪道
- 單接口用例: 正常數據/邊界數據/異常數據(健壯性)/並發(一致性)/性能/安全性(抓包截取偽造/SQL注入/跨域請求)
- 場景用例: 列出常見的用戶場景, 用接口進行覆蓋, 業務場景壓測(尋找某個環節的性能瓶頸)
TestCase | Url | Method | DataType | a | b | Excepted | Actual | Status |
---|---|---|---|---|---|---|---|---|
test_add_normal | /api/add/ | GET | Url | 3 | 5 | 8 | ||
test_add_zero | /api/add/ | POST | FORM | 0 | 0 | 0 | ||
test_add_negetive | /api/add/ | POST | FORM | -3 | 5 | 2 | ||
test_add_float | /api/add/ | POST | FORM | 3.2 | 5.2 | 8.4 | ||
test_add_null | /api/add/ | POST | FORM | 0 |
執行接口測試
- Postman: 功能調試
- Jmeter: 性能
接口自動化實踐
五步教會你寫接口自動化用例
需要安裝三方包:requests pytest pytest-html
pip install requests pytest pytest-html
- 導入requests模塊
import requests - 組裝請求參數和數據
url = 'http://127.0.0.1:5000/add/'
params = {"a":3, "b":5} # get請求url參數, 字典格式
data = {"a":3, "b":5} # post請求請求數據, 字典格式
- 發送請求得到response對象
resp = requests.get(url=url, params=params)
resp = requests.post(url=url,data=data)
- 解析response對象
- resp.text # 獲取響應文本
- 斷言結果
assert resp.text == '8'
完整代碼:
# 1. 導入包
import requests
base_url = "http://127.0.0.1:5005"
# 2. 組裝請求
def test_add_normal():
# url 字符串格式
url = base_url + "/add/"
# data {} 字典格式
data = {"a": "1", "b": "2"}
# 3. 發送請求,獲取響應對象
response = requests.post(url=url, data=data)
# 4. 解析響應
# 5. 斷言結果
assert response.text == '3'
REST類接口自動測試方法
請求格式為json
三處不同:
- 必須通過headers指定內容類型為application/json: ```headers={"Content-Type":"application/json"}
- 請求數據要轉化為字符串:
data=json.dumps(data)
(使用json.dumps需要import json) - json格式的響應數據,在接口調試通過和穩定的情況下可以使用response.json()解析為字典格式,進行斷言
完整代碼:
# 1. 導入包
import requests
import json
base_url = "http://127.0.0.1:5005"
def test_sub_normal():
url = base_url + "/api/sub/"
headers = {"Content-Type": "application/json"} # 1. 必須通過headers指定請求內容類型為json
data = {"a": "4", "b": "2"}
data = json.dumps(data) # 2. 序列化成字符串
response = requests.post(url=url, headers=headers, data=data)
# 3. 響應解析 # 響應格式為: {"code":"100000", "msg": "成功", "data": "2"}
resp_code = response.json().get("code")
resp_msg = response.json().get("msg")
resp_data = response.json().get("data")
# 斷言
assert response.status_code == 200
assert resp_code == "100000"
assert resp_msg == "成功"
assert resp_data == "2"
補充1: 感受Python黑科技之exec()動態生成用例:
數據文件: test_add_data.xls
TestCase | Url | Method | DataType | a | b | Excepted | Actual | Status |
---|---|---|---|---|---|---|---|---|
test_add_normal | /api/add/ | GET | Url | 3 | 5 | 8 | ||
test_add_zero | /api/add/ | POST | FORM | 0 | 0 | 0 | ||
test_add_negetive | /api/add/ | POST | FORM | -3 | 5 | 2 | ||
test_add_float | /api/add/ | POST | FORM | 3.2 | 5.2 | 8.4 | ||
test_add_null | /api/add/ | POST | FORM | 0 |
import requests
import xlrd
base_url = 'http://127.0.0.1:5005'
# 1.打開excel
wb = xlrd.open_workbook("test_add_data.xls")
# 2. 獲取sheet
sh = wb.sheet_by_index(0) # wb.sheet_by_name("Sheet1")
# 行數 sh.nrows 列數 sh.ncols
# 獲取單元格數據
# print(sh.cell(1,0).value)
# print(sh.nrows)
tpl = '''def {case_name}():
url = base_url + '/add/'
data = {{"a": "{a}", "b":"{b}"}}
response = requests.get(url=url, data=data)
assert response.text == '{expected}'
'''
for row in range(1, sh.nrows):
case_name = sh.cell(row,0).value
a = sh.cell(row, 4).value
b = sh.cell(row, 5).value
expected = sh.cell(row, 6).value
case = tpl.format(case_name=case_name, a=a, b=b, expected=expected)
exec(case)
動態生成的用例支持pytest發現和執行
自動化接口用例運行
- 將自動化測試用例保存為test*.py,一個文件里可以寫多個用例, 如上面兩個接口保存為test_user.py
- 在自動化用例腳本所在目錄打開命令行, 運行
pytest
(運行所有test開頭的.py用例)或pytest test_user.py
(只運行該腳本中用例) - pytest一些參數
- -q: 安靜模式(不顯示環境信息)
pytest -q test_user.py
- --html=report.html:執行完生成report.html報告(文件名可以自己指定)
pytest test_user.py --html=test_user_report.html
- --resultlog=test.log: 執行完成生成執行結果log文件
pytest test_user.py --resultlog=run.log
- -q: 安靜模式(不顯示環境信息)
requests庫詳解
請求方法
- requests.get()
- requests.post()
- requests.delete()
- .....
- requests.session() # 用來保持session會話,如登錄狀態
請求參數
- url: 接口地址, str
url="http://127.0.0.1:5000/add/"
- headers: 請求頭, dict
headers={"Content-Type": "application/json"}
- params: url參數, dict
params={"a":"1":"b":"2"}
- data: 請求數據, dict
data={"a":"1":"b":"2"}
- files: 文件句柄, dict
files={"file": open("1.jpg")}
- timeout: 超時時間,單位s, str, 超過時間會報超時錯誤```requests.get(url=url,params=params,timeout=10)
響應解析
- resp: 響應對象
- resp.status_code: 響應狀態碼
- resp.text # 響應文本
- resp.json() # 響應轉化為json對象(字典)-慎用:如果接口出錯或返回格式不是json格式,使用這個方法會報錯
- resp.content # 響應內容, 二進制類型