Python 裝飾器工廠在接口自動化中的六種高級用法
裝飾器工廠(Decorator Factory)在 接口自動化測試框架 中有非常廣泛的應用。它不僅可以提升代碼的可讀性和復用性,還能幫助我們實現:
1、接口日志記錄
2、異常重試機制
3、權限校驗
4、性能監控
5、數據驅動
6、環境切換
前提準備:定義一個通用接口函數模板
import requests
from functools import wraps
1. 日志記錄裝飾器工廠(支持不同級別)
功能說明:
根據傳入的日志級別(info/debug),記錄接口調用信息。
實現代碼:
def make_logger(level='info', enabled=True):
def logger_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if not enabled:
return func(*args, **kwargs)
log_method = {
'info': logging.info,
'debug': logging.debug
}.get(level.lower(), logging.info)
log_method(f"[{func.__name__}] 正在調用接口...")
result = func(*args, **kwargs)
log_method(f"[{func.__name__}] 接口調用完成")
return result
return wrapper
return logger_decorator
使用示例:
@make_logger('debug')
def get_user_info(user_id):
print(f"獲取用戶 {user_id} 的信息")
get_user_info(1001)
?? 輸出:
2025-06-29 14:30:00,123 [DEBUG] [get_user_info] 正在調用接口...
獲取用戶 1001 的信息
2025-06-29 14:30:00,124 [DEBUG] [get_user_info] 接口調用完成
2. 接口異常自動重試裝飾器工廠
功能說明:
封裝一個通用的重試邏輯,失敗時自動重試 N 次,適用于網絡請求等不穩定操作。
實現代碼:
def retry(max_retries=3, delay=1, exceptinotallow=(Exception,)):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
retries = 0
while retries <= max_retries:
try:
return func(*args, **kwargs)
except exceptions as e:
retries += 1
logging.warning(f"[{func.__name__}] 第 {retries}/{max_retries} 次重試失敗: {e}")
if retries > max_retries:
raise
time.sleep(delay)
return None
return wrapper
return decorator
使用示例:
@retry(max_retries=3, exceptinotallow=(requests.exceptions.RequestException,))
def fetch_data(url):
response = requests.get(url)
return response.json()
try:
data = fetch_data("https://api.example.com/data")
print(data)
except Exception as e:
print("最終請求失敗:", e)
3. 權限驗證裝飾器工廠(支持角色控制)
功能說明:
根據不同用戶角色(如 admin、user)決定是否允許執行某個接口。
實現代碼:
def permission_required(role='user'):
def decorator(func):
@wraps(func)
def wrapper(context, *args, **kwargs):
user_role = context.get('role')
if user_role != role:
logging.error(f"[{func.__name__}] 權限不足,需要 {role} 角色,當前為 {user_role}")
raise PermissionError(f"權限不足,需要 {role} 角色")
return func(context, *args, **kwargs)
return wrapper
return decorator
使用示例:
@permission_required('admin')
def delete_user(context, user_id):
print(f"管理員 {context['username']} 刪除了用戶 {user_id}")
context = {'username': '張三', 'role': 'admin'}
delete_user(context, 1002)
4. 接口性能統計裝飾器工廠
功能說明:
記錄接口執行時間,用于性能分析或優化。
實現代碼:
import time
def performance_monitor(enabled=True):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if not enabled:
return func(*args, **kwargs)
start = time.time()
result = func(*args, **kwargs)
duration = time.time() - start
logging.info(f"[{func.__name__}] 執行耗時: {duration:.4f} 秒")
return result
return wrapper
return decorator
使用示例:
@performance_monitor()
def slow_api():
time.sleep(1.2)
slow_api()
?? 輸出:
[slow_api] 執行耗時: 1.2003 秒
5. 數據驅動裝飾器工廠(參數化測試)
功能說明:
為接口函數動態注入測試數據,實現參數化測試。
實現代碼:
def data_provider(data_list):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for data in data_list:
logging.info(f"運行測試用例: {data}")
func(*data)
return wrapper
return decorator
使用示例:
@test_data([
("張三", "北京"),
("李四", "上海"),
("王五", "廣州")
])
def test_user_location(name, city):
print(f"{name} 的城市是 {city}")
test_user_location()
?? 輸出:
運行測試用例: ('張三', '北京')
張三 的城市是 北京
運行測試用例: ('李四', '上海')
李四 的城市是 上海
...
6. 環境切換裝飾器工廠(開發/測試/生產)
功能說明:
根據環境配置自動切換接口地址或行為。
實現代碼:
def environment_switch(env='dev'):
base_urls = {
'dev': 'http://dev.api.example.com',
'test': 'http://test.api.example.com',
'prod': 'http://api.example.com'
}
def decorator(func):
@wraps(func)
def wrapper(endpoint, *args, **kwargs):
full_url = f"{base_urls[env]}/{endpoint}"
logging.info(f"[{func.__name__}] 請求地址: {full_url}")
return func(full_url, *args, **kwargs)
return wrapper
return decorator
使用示例:
@environment_switch('test')
def call_api(url):
print(f"正在調用接口: {url}")
call_api("users/list")
?? 輸出:
[test_api] 請求地址: http://test.api.example.com/users/list
正在調用接口: http://test.api.example.com/users/list
?? 總結表格:6 種裝飾器工廠對比
圖片