Как использовать временные каталоги и файлы в тестах
Фикстура tmp_path
Можно использовать фикстуру tmp_path, которая предоставляет временный каталог, уникальный для каждой тестовой функции.
tmp_path — это объект pathlib.Path. Пример использования в тесте:
# content of test_tmp_path.py
CONTENT = "content"
def test_create_file(tmp_path):
d = tmp_path / "sub"
d.mkdir()
p = d / "hello.txt"
p.write_text(CONTENT, encoding="utf-8")
assert p.read_text(encoding="utf-8") == CONTENT
assert len(list(tmp_path.iterdir())) == 1
assert 0
При запуске тест будет пройден, за исключением последней строки assert 0, которую мы используем для просмотра значений:
$ pytest test_tmp_path.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-9.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
test_tmp_path.py F [100%]
================================= FAILURES =================================
_____________________________ test_create_file _____________________________
tmp_path = PosixPath('PYTEST_TMPDIR/test_create_file0')
def test_create_file(tmp_path):
d = tmp_path / "sub"
d.mkdir()
p = d / "hello.txt"
p.write_text(CONTENT, encoding="utf-8")
assert p.read_text(encoding="utf-8") == CONTENT
assert len(list(tmp_path.iterdir())) == 1
> assert 0
E assert 0
test_tmp_path.py:11: AssertionError
========================= short test summary info ==========================
FAILED test_tmp_path.py::test_create_file - assert 0
============================ 1 failed in 0.12s =============================
По умолчанию pytest сохраняет временный каталог для последних 3 запусков pytest. Параллельные запуски одной и той же тестовой функции поддерживаются настройкой базового временного каталога, уникального для каждого параллельного запуска. Подробности см. в разделе Расположение и хранение временных каталогов.
Фикстура tmp_path_factory
tmp_path_factory — это фикстура с областью видимости сеанса, которую можно использовать для создания произвольных временных каталогов из любой другой фикстуры или теста.
Предположим, например, что для набора тестов требуется большое изображение на диске, созданное программно. Вместо того чтобы вычислять одно и то же изображение для каждого теста, который его использует, в отдельном tmp_path, можно создать его один раз за сеанс и сэкономить время:
# contents of conftest.py
import pytest
@pytest.fixture(scope="session")
def image_file(tmp_path_factory):
img = compute_expensive_image()
fn = tmp_path_factory.mktemp("data") / "img.png"
img.save(fn)
return fn
# contents of test_image.py
def test_histogram(image_file):
img = load_image(image_file)
# compute and test histogram
Подробности см. в разделе API tmp_path_factory.
Фикстуры tmpdir и tmpdir_factory
Фикстуры tmpdir и tmpdir_factory похожи на tmp_path и tmp_path_factory, но используют/возвращают устаревшие объекты py.path.local, а не стандартные объекты pathlib.Path.
Примечание
В настоящее время предпочтительно использовать tmp_path и tmp_path_factory.
Чтобы помочь модернизировать старые кодовые базы, можно запустить pytest с отключённым плагином legacypath:
pytest -p no:legacypath
Это вызовет ошибки в тестах, использующих устаревшие пути. Эту настройку также можно задать постоянно с помощью параметра addopts в файле конфигурации.
Подробности см. в документации API tmpdir и tmpdir_factory.
Расположение и хранение временных каталогов
Временные каталоги, возвращаемые фикстурами tmp_path и (теперь устаревшей) tmpdir, автоматически создаются внутри базового временного каталога. Его структура зависит от параметра --basetemp:
-
По умолчанию (если параметр
--basetempне задан) временные каталоги создаются по следующему шаблону:{temproot}/pytest-of-{user}/pytest-{num}/{testname}/где:
-
{temproot}— системный временный каталог, определяемый функциейtempfile.gettempdir(). Его можно переопределить с помощью переменной окруженияPYTEST_DEBUG_TEMPROOT. -
{user}— имя пользователя, запускающего тесты, -
{num}— число, увеличиваемое при каждом запуске набора тестов, -
{testname}— очищенная версияthe name of the current test.
Автоматически увеличиваемый заполнитель
{num}обеспечивает базовое хранение результатов и предотвращает бездумное удаление результатов предыдущих запусков тестов. По умолчанию сохраняются последние 3 временных каталога, но это поведение можно настроить с помощью параметровtmp_path_retention_countиtmp_path_retention_policy. -
-
Если используется параметр
--basetemp(например,pytest --basetemp=mydir), указанный каталог будет напрямую использоваться в качестве базового временного каталога:{basetemp}/{testname}/Обратите внимание, что в этом случае результаты не хранятся: сохраняются только результаты последнего запуска.
Предупреждение
Каталог, указанный для параметра
--basetemp, будет без предупреждения очищаться перед каждым запуском тестов, поэтому используйте для этой цели отдельный каталог.
При распределении тестов на локальном компьютере с помощью pytest-xdist автоматически настраивается каталог basetemp для подпроцессов, чтобы все временные данные размещались внутри одного временного каталога для каждого запуска тестов.
© 2015–2026 Holger Krekel and pytest-dev team
Licensed under the MIT License.
https://docs.pytest.org/en/stable/how-to/tmp_path.html