Фикстуры в pytest — это мощный механизм для подготовки и очистки тестового окружения. Они позволяют выносить повторяющийся код из тестов и управлять тестовыми данными.
import pytest
@pytest.fixture
def sample_data():
# Эта часть выполняется перед тестом
data = {"a": 1, "b": 2}
yield data # Передаем данные в тест
# Эта часть выполняется после теста (очистка)
print("Cleanup")
def test_sample(sample_data):
assert sample_data["a"] == 1
Фикстуры могут иметь разную область видимости:
@pytest.fixture(scope="function") # По умолчанию - создается для каждого теста
def func_scope():
return "function"
@pytest.fixture(scope="class") # Один раз на класс
def class_scope():
return "class"
@pytest.fixture(scope="module") # Один раз на модуль
def module_scope():
return "module"
@pytest.fixture(scope="session") # Один раз на сессию тестов
def session_scope():
return "session"
Фикстуры могут выполняться автоматически без явного вызова:
@pytest.fixture(autouse=True)
def auto_fixture():
print("\nThis runs before each test")
def test_example():
assert True # auto_fixture выполнится автоматически
@pytest.fixture(params=[1, 2, 3])
def parametrized_fixture(request):
return request.param * 2
def test_parametrized(parametrized_fixture):
assert parametrized_fixture in [2, 4, 6]
Pytest предоставляет полезные встроенные фикстуры:
Пример с tmp_path:
def test_create_file(tmp_path):
file = tmp_path / "test.txt"
file.write_text("content")
assert file.read_text() == "content"
@pytest.fixture(scope="class")
def db_connection():
conn = create_db_connection()
yield conn
conn.close()
@pytest.mark.usefixtures("db_connection")
class TestDatabase:
def test_query1(self):
assert True
def test_query2(self):
assert True
Альтернатива yield для очистки:
@pytest.fixture
def resource(request):
res = allocate_resource()
def cleanup():
res.release()
request.addfinalizer(cleanup)
return res
@pytest.fixture
def dynamic_fixture(request):
marker = request.node.get_closest_marker("data")
if marker:
return marker.args[0]
return "default"
@pytest.mark.data("custom")
def test_dynamic(dynamic_fixture):
assert dynamic_fixture == "custom"
Фикстуры можно выносить в файл conftest.py
для общего доступа:
# conftest.py
import pytest
@pytest.fixture
def shared_fixture():
return "shared"
# test_file.py
def test_shared(shared_fixture):
assert shared_fixture == "shared"
@pytest.fixture
def user():
return {"name": "Alice"}
@pytest.fixture
def active_user(user):
user["active"] = True
return user
def test_user(active_user):
assert active_user["active"] is True
db_connection
, а не fixture1
Правильное использование фикстур делает тесты:
Начните с простых фикстур и постепенно осваивайте более сложные возможности.