python - Pytest:使用 python 线程在程序中模拟/修补 sys.stdin

标签 python unit-testing mocking pytest monkeypatching

我已经获得了一些在重构之前需要测试的代码。它使用深度递归,因此设置新的限制,然后在新线程中运行自身:

sys.setrecursionlimit(10**6)
threading.stack_size(2**27)
...
threading.Thread(target=main).start()

该代码严重依赖于 sys.stdinsys.stdout 例如

class SpamClass:
    def read(self):
        self.n = int(sys.stdin.readline())
        ...
        for i in range(self.n):
            [a, b, c] = map(int, sys.stdin.readline().split())
    ...
    def write(self)
        print(" ".join(str(x) for x in spam()))

为了测试代码,我需要传入一系列输入文件的内容,并将结果与​​一些相应示例输出文件的内容进行比较。

到目前为止,我已经尝试了三四种不同类型的模拟和修补,但没有成功。我的其他测试都是为 pytest 编写的,因此必须使用其他东西确实很麻烦。

我尝试使用 StringIO 修补 module.sys.stdin,但这似乎不起作用,因为 pytest 的 capsys 设置了 sys.stdin 为 null,因此尽管有补丁,仍会引发错误。

我还尝试使用 pytest 的 monkeypatch 固定装置将 module.SpamClss.read 方法替换为测试中定义的函数,但这会产生段错误,因为,我认为,在测试之前退出的线程(或......?)。

'pytest test_spam.py' terminated by signal SIGBUS (Misaligned address error)

关于如何正确执行此操作有什么建议吗?非常感谢。

最佳答案

嗯,我仍然不知道问题出在哪里,也不知道我做得是否正确,但它现在有效。我不确定线程​​方面是否正常工作,但其余部分似乎都很好。

@pytest.mark.parametrize("inputs, outputs", helpers.get_sample_tests('spampath'))
def test_tree_orders(capsys, inputs, outputs):
    """
    """
    with patch('module.sys.stdin', StringIO("".join(inputs))):
        module.threading.Thread(target=module.main()).start()

    captured = capsys.readouterr()

    assert "".join(outputs) == captured.out

对于其他感兴趣的人,将调试打印为 print(spam, file=sys.stderr) 会有所帮助,然后您可以在测试中将其访问为 captured.err ,参见。用于测试的 captured.out

关于python - Pytest:使用 python 线程在程序中模拟/修补 sys.stdin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50411570/

相关文章:

python - 将 odbc 驱动程序安装到 azure 应用服务

php - 在套件中的每个测试之前运行设置代码

javascript - 如何为 express.static 模拟 http.ServerResponse 和 http.IncomingMessage

java - mockito 验证与 ArgumentCaptor 的交互

python - 自定义 Django 表单未显示 - 使用 Wagtail

python - PyDev 不会自动完成某些模块(至少是 numpy、matplotlib)

unit-testing - 如何用 PHPUnit 模拟这些方法?

reactjs - TypeError : _mapboxGl. default.Map 不是构造函数

python - 如何有效地替换 pandas 列中日期时间值的时间部分?

c# - 在系统测试中使用 Selenium 时,使用 Thread.Sleep 的替代方法是什么?