Как я могу воспроизводимо (py)протестировать режим сбоя кода, открывающего файл, если файл отсутствует?

#python #pytest

Вопрос:

Я хотел бы написать тестовый пример поведения функции, которая открывает файл в случае, если этот файл не существует.

Я думаю, что вопрос сводится к другому, а именно: «Как я могу быть уверен, что путь к файлу не существует в файловой системе?»

 import pytest

def file_content(file_name):
    with open(file_name, "r") as f:
        return f.read()

def test_file_content_file_not_found():
    file_name_of_inexistent_file = "???"
    with pytest.raises(FileNotFoundError):
        file_content(file_name_of_inexistent_file)

test_file_content_file_not_found()
 

"???" я думаю, что какой-то отличный инструмент реализует разумный и безопасный способ создания имени файла или макетной файловой системы, который гарантирует, что сбой гарантирован, но также не требует изменения файловой системы.

На данный момент у меня есть небольшая вспомогательная функция, которая генерирует случайные строки, которые проверяются, являются ли они существующими файлами, и если они не возвращаются. Таким образом, я могу имитировать желаемое поведение. Тем не менее, я думаю, что должен быть более стандартный способ достичь этого.

Комментарии:

1. Можно было бы издеваться над файловой системой с помощью PyFilesystem или аналогичного инструмента, но это добавило бы зависимость к коду только для тестирования, что нежелательно.

2. На самом деле, вы можете просто передать пустую строку в качестве имени файла, которое выдаст FileNotFoundError

3. @OlvinRoght Это очень элегантное решение! Спасибо.

Ответ №1:

самый простой способ-использовать встроенное tmp_path приспособление для создания уникального пустого каталога:

 def test_does_not_exist(tmp_path):
    with pytest.raises(FileNotFoundError):
        file_content(tmp_path.joinpath('dne'))
 

tmp_path генерируется для каждого теста и будет начинаться пустым, поэтому dne никогда не будет существовать

если вам нужно универсальное, не самое сложное решение, вы можете использовать tempfile.TemporaryDirectory его напрямую:

 with tempfile.TemporaryDirectory() as tmpdir:
    with pytest.raises(FileNotFoundError):
        file_content(os.path.join(tmpdir, 'dne'))
 

Отказ от ответственности: Я самый ядровый разработчик