编写pytest函数来检查输出到python中的文件?

bra*_*orm 15 python file-io function pytest

我问了这个问题,关于如何写一个pytest来检查输出stdout并得到一个解决方案.现在我需要写一个test case,检查内容是否写入文件,内容是否按预期写入,例如:

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

现在是一个pytest函数来检查它是否写入:

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

虽然这似乎有效,但我认为这不是理想的,尤其是硬编码.这些test functions写入文件通常是如何编写的?

flu*_*lub 21

有一个tmpdir fixture会创建一个per-test临时目录.所以测试看起来像这样:

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'
Run Code Online (Sandbox Code Playgroud)

在这里,您重构代码也不是硬编码,这是测试代码如何使您更好地设计它的一个主要示例.

  • 它会创建一个您可以在之后检查的真实目录,在UNIX上,您通常会在`/ tmp/pytest-xxxx`中找到它们,并带有最新运行的符号链接.您可以通过调用`py.test --fixtures来了解灯具,有关tmpdir的情况,请参阅http://pytest.org/latest/tmpdir.html了解更多详情. (2认同)

Enr*_* M. 9

假设您在名为 的文件中有这个“惊人”的软件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.")
Run Code Online (Sandbox Code Playgroud)

要测试该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")
Run Code Online (Sandbox Code Playgroud)

我总是尽量避免将文件写入磁盘,即使它是一个专用于我的测试的临时文件夹:实际上不接触磁盘会使您的测试更快,尤其是当您在代码中与文件进行大量交互时。

  • 我不会说“总是”避免做任何事情。有时您想要断言您的代码实际上按照您认为的方式处理文件系统。 (3认同)
  • 这应该是正确的答案。始终避免在测试中向磁盘写入/从磁盘读取。虽然它可能更“罗嗦”,但测试将运行得更快,并且比 flub 提供的答案更能隔离正在测试的内容 (2认同)