Запись функции pytest для проверки вывода в файл на python?

Я спросил этот вопрос о том, как написать pytest для проверки вывода в stdout и получил решение. Теперь мне нужно написать test case, чтобы проверить, записано ли содержимое в файл и что содержимое написано как ожидалось например:

def writetoafile():
   file = open("output.txt",w)
   file.write("hello\n")
   file.write("world\n")
   file.close()

теперь функция pytest, чтобы проверить, записано ли это:

def test_writeToFile():
    file = open("ouput.txt",'r')
    expected = "hello\nworld\n"
    assert expected==file.read()

хотя это, похоже, работает, я не думаю, что это идеально, особенно жесткое кодирование. как этот тип test functions записи в файл обычно пишется?

Ответ 1

Существует tmpdir fixture, который создаст вам временный каталог для каждого теста. Таким образом, тест будет выглядеть примерно так:

def writetoafile(fname):
    with open(fname, 'w') as fp:
        fp.write('Hello\n')

def test_writetofile(tmpdir):
    file = tmpdir.join('output.txt')
    writetoafile(file.strpath)  # or use str(file)
    assert file.read() == 'Hello\n'

Здесь вы рефакторинг кода, чтобы он не был жестко запрограммирован, что является ярким примером того, как тестирование вашего кода заставляет вас лучше его проектировать.

Ответ 2

Предположим, у вас есть этот "удивительный" фрагмент программного обеспечения в файле с именем main.py:

"""
main.py
"""

def write_to_file(text):
    with open("output.txt", "w") as h:
        h.write(text)

if __name__ == "__main__":
    write_to_file("Every great dream begins with a dreamer.")

Чтобы протестировать метод write_to_file, вы можете записать что-то вроде этого в файл в той же папке с именем test_main.py:

"""
test_main.py
"""
from unittest.mock import patch, mock_open

import main


def test_do_stuff_with_file():
    open_mock = mock_open()
    with patch("main.open", open_mock, create=True):
        main.write_to_file("test-data")

    open_mock.assert_called_with("output.txt", "w")
    open_mock.return_value.write.assert_called_once_with("test-data")

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