Python接口測試課程(第二天)-接口測試快速實踐


目錄

Python接口測試課程(第一天)-Python基礎
Python接口測試課程(第二天)-接口測試快速實踐
Python接口測試課程(第三天)-接口安全驗證,參數化及斷言
Python接口測試課程(第四天)-接口測試框架實現

PDF下載:鏈接:https://pan.baidu.com/s/1x3_LYq23F_1LviGVbRNFXw 密碼:xrcj

更多學習資料請加添加作者微信:superz-han 獲取

第二天: Python接口測試(一)

簡單接口搭建(表單/REST)

五步教會你寫接口

首先要安裝flask包: pip install flask

  1. 從flask中導入Flask類和request對象: from flask import Flask, request
  2. 從當前模塊實例化出一個Flask實例:app=Flask(__name__)
  3. 編寫一個函數來處理請求
    1. 從請求對象中獲取數據:a=request.values.get("a");b=request.values.get("b")
      • request.params: 字典格式,存儲請求中的url參數
      • request.form: 字典格式,存儲請求中的表單數據
      • request.values: 字典格式, 包含params和form中的值
      • request.json: 字典格式, 存儲json類型的請求數據, 如果請求類型非json, 值為空
    2. 進行業務處理: sum = int(a) + int(b)
    3. 組裝並返回響應數據: return str(sum) # http一般使用字符串傳輸數據
  4. 為接口指定接口地址和接受的方法:@app.route("/add/", methods=["GET"]) # 寫到函數上面(裝飾器)
  5. 運行接口:
    1. 最后添加:
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-htmlpip install requests pytest pytest-html

  1. 導入requests模塊
    import requests
  2. 組裝請求參數和數據
    url = 'http://127.0.0.1:5000/add/'
    params = {"a":3, "b":5} # get請求url參數, 字典格式
    data = {"a":3, "b":5} # post請求請求數據, 字典格式
  3. 發送請求得到response對象
    resp = requests.get(url=url, params=params)
    resp = requests.post(url=url,data=data)
  4. 解析response對象
    • resp.text # 獲取響應文本
  5. 斷言結果
    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

三處不同:

  1. 必須通過headers指定內容類型為application/json: ```headers={"Content-Type":"application/json"}
  2. 請求數據要轉化為字符串: data=json.dumps(data) (使用json.dumps需要import json)
  3. 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發現和執行

自動化接口用例運行

  1. 將自動化測試用例保存為test*.py,一個文件里可以寫多個用例, 如上面兩個接口保存為test_user.py
  2. 在自動化用例腳本所在目錄打開命令行, 運行pytest(運行所有test開頭的.py用例)或pytest test_user.py(只運行該腳本中用例)
  3. 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

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 # 響應內容, 二進制類型


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM