使用 Pytest 测试 Python 程序

Using Pytest to test a Python Program

TI 是 Python 编程的新手,对使用 Pytest 进行测试有疑问。在高层次上,我有一个程序需要 3 个用户输入并最终生成一个文本文件。对于我的测试,我想基本上将我的程序输出的文件与它应该输出的文件进行比较。

现在,我不确定如何进行测试。该程序本身不带任何参数,但仅依赖于 3 个用户输入,我将使用 monkeypatch 来模拟这些输入。我是否创建一个名为 program_test.py 的新 python 文件并在此处包含调用原始程序的方法?我试过这个,但我在实际调用原始程序和发送模拟输入时遇到了问题。或者,我是否在原始程序中进行了测试(这对我来说意义不大)。

我想要这样的东西:

import my_program

def test_1():
    inputs = iter(['input1', 'input2', 'input3'])
    monkeypatch.setattr('builtins.input', lambda x: next(inputs))
    my_program
    # now do some assertion with some file comparison
    # pseudocode
    assert filecompare.cmp(expectedfile, actualfile)

这似乎是 运行 原始程序,我认为它与导入语句有关,即它从来不是 运行 test_1(),可能是因为我从不调用它?如有任何帮助,我们将不胜感激!

如果不提供您的 my_program 代码,则很难判断发生了什么。

既然你提到了 import 问题,我猜你没有定义 main()if __name__ == "__main__".

这里有一个关于如何测试它的小例子。

首先,构建您的 my_program 以具有包含代码的 main 函数,然后添加 if __name__ == "__main__" 这将使您能够 运行 main 函数如果 my_program 直接执行但也将 my_program 作为模块导入到其他文件(没有 运行ning 它,更多信息请参见:What does if name == "main": do?)。

my_program:

def main():
    x = input()
    y = input()
    z = input()
    with open("test", "w") as f_out:
        f_out.write(f"{x}-{y}-{z}")


if __name__ == "__main__":
    main()

现在您可以创建一个test.py文件并测试my_programmain功能:

import os
import filecmp
import my_program


def test_success(monkeypatch):
    inputs = ["input1", "input2", "input3"]
    monkeypatch.setattr("builtins.input", lambda: next(iter(inputs)))
    my_program.main()
    with open("expected", "w") as f_out:
        f_out.write("-".join(inputs))
    assert filecmp.cmp("expected", "test")
    os.remove("test")
    os.remove("expected")


def test_fail(monkeypatch):
    inputs = ["input1", "input2", "input3"]
    monkeypatch.setattr("builtins.input", lambda: next(iter(inputs)))
    my_program.main()
    with open("expected", "w") as f_out:
        f_out.write("something-else-test")
    assert not filecmp.cmp("expected", "test")
    os.remove("test")
    os.remove("expected")

This is an example so I used os.remove to delete the files. Ideally you would define fixtures in your tests to use tempfile and generate random temporary files which will be automatically deleted after your tests.