【问题标题】:Pytest: mock/patch sys.stdin in program using threading with pythonPytest:在程序中使用 python 线程模拟/修补 sys.stdin
【发布时间】:2018-05-18 12:40:18
【问题描述】:

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

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 的capsyssys.stdin 设置为null,因此尽管有修补程序仍会引发错误。

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

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

关于如何正确执行此操作的任何建议?非常感谢。

【问题讨论】:

    标签: python unit-testing mocking pytest monkeypatching


    【解决方案1】:

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

    @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 用于测试。

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-03
      • 1970-01-01
      • 2021-08-31
      相关资源
      最近更新 更多