Как использовать временные каталоги и файлы в тестах

Приспособление tmp_path

Вы можете использовать приспособление tmp_path, которое предоставит временный каталог, уникальный для данного тестового вызова, созданный в base temporary directory.

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)
    assert p.read_text() == 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-7.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)
        assert p.read_text() == 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 =============================

Приспособление 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

Подробнее см. в разделе tmp_path_factory API.

Фиксаторы 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 в конфигурационном файле.

Подробности см. в разделе tmpdir tmpdir_factory API.

Базовый временный каталог по умолчанию

Временные каталоги по умолчанию создаются как подкаталоги системного временного каталога. Базовое имя будет pytest-NUM, где NUM будет увеличиваться с каждым запуском теста. Более того, записи старше 3 временных каталогов будут удаляться.

Количество записей в настоящее время нельзя изменить, но использование опции --basetemp удалит каталог перед каждым запуском, что означает сохранение временных каталогов только самого последнего запуска.

Вы можете отменить настройки временного каталога по умолчанию следующим образом:

pytest --basetemp=mydir

Предупреждение

Содержимое mydir будет полностью удалено, поэтому убедитесь, что каталог используется только для этой цели.

При распространении тестов на локальной машине с помощью pytest-xdist необходимо автоматически настроить каталог basetemp для подпроцессов таким образом, чтобы все временные данные располагались под единственным каталогом basetemp для каждого теста.

Вернуться на верх