[英]How do I reset Python runtime between pytest test_functions?
我正在使用 pytest 來測試創建 prometheus Python 客戶端以導出指標的代碼。
在測試功能之間,prometheus 客戶端不會重置(因為它具有內部狀態),這會搞砸我的測試。
我正在尋找一種在所有測試 function 調用之前基本上獲得新的 Pyhon 運行時的方法。 這樣,prometheus 客戶端的內部 state 有望重置為 Python 運行時開始執行我的測試時的 state。
我已經嘗試過importlib.reload()
但這不起作用。
如果您想使用“干凈”的 Prometheus 客戶端開始每個測試,那么我認為最好將其創建並拆除到帶有 function scope 的夾具(它實際上是默認范圍),如下所示:
@pytest.fixture(scope=function)
def prometheus_client(arg1, arg2, etc...)
#create your client here
yield client
#remove your client here
然后你使用這個夾具定義你的測試:
def test_number_one(prometheus_client):
#test body
這樣客戶端在每個測試中都是從頭開始創建的,即使測試失敗也會被刪除。
首先,讓我展示一下我認為您應該如何在測試中使用指標(以及我如何在我的項目中這樣做)。 我沒有進行重置,而是在測試開始之前跟蹤指標值。 測試完成后,我再次收集指標並分析兩個值之間的差異。 帶有計數器的 django 視圖測試示例:
import copy
import prometheus_client
import pytest
from django.test import Client
from django.urls import reverse
def find_value(metrics, metric_name):
return next((
sample.value
for metric in metrics
for sample in metric.samples
if sample.name == metric_name
), None)
@pytest.fixture
def metrics_before():
yield copy.deepcopy(list(prometheus_client.REGISTRY.collect()))
@pytest.fixture
def client():
return APIClient()
def test_counter_increases_by_one(client, metrics_before):
# record the metric value before the HTTP client requests the view
value_before = find_value(metrics_before, 'http_requests_total') or 0.0
# do the request
client.get('/my-view/')
# collect the metric value again
metrics_after = prometheus_client.REGISTRY.collect()
value_after = find_value(metrics_after, 'http_requests_total')
# the value should have increased by one
assert value_after == value_before + 1.0
現在讓我們看看注冊表本身可以做什么。 請注意,這使用了prometheus-client
內部結構,並且根據定義是脆弱的 - 使用風險自負!
prometheus-client
內部混淆:取消注冊所有指標如果您確定您的測試代碼將從頭開始調用指標注冊,您可以在測試開始之前從注冊表中取消注冊所有指標:
@pytest.fixture(autouse=True)
def clear_registry():
collectors = tuple(prometheus_client.REGISTRY._collector_to_names.keys())
for collector in collectors:
prometheus_client.REGISTRY.unregister(collector)
yield
請注意,這僅在您的測試代碼再次調用指標注冊時才有效,否則。 您將有效地停止指標收集,例如,內置的PlatformCollector
將消失,直到您再次明確注冊它,例如通過prometheus_client.PlatformCollector()
創建一個新實例。
prometheus-client
內部結構混淆:重置(幾乎)所有指標您還可以重置已注冊指標的值:
@pytest.fixture(autouse=True)
def reset_registry():
collectors = tuple(prometheus_client.REGISTRY._collector_to_names.keys())
for collector in collectors:
try:
collector._metrics.clear()
collector._metric_init()
except AttributeError:
pass # built-in collectors don't inherit from MetricsWrapperBase
yield
這將重新實例化所有計數器/儀表/直方圖等的值和指標。上面的測試現在可以寫成
def test_counter_increases_by_one(client):
# do the request
client.get('/my-view/')
# collect the metric value
metrics_after = prometheus_client.REGISTRY.collect()
value_after = find_value(metrics_after, 'http_requests_total')
# the value should be one
assert value_after == 1.0
當然,這不會重置內置收集器的任何指標,例如PlatformCollector
因為它在實例化時只抓取一次值,或者ProcessCollector
因為它根本不存儲任何值,而是從操作系統重新讀取它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.