我已经获得了一些在重构之前需要测试的代码。它使用深度递归,因此设置新的限制,然后在新线程中运行自身:
sys.setrecursionlimit(10**6)
threading.stack_size(2**27)
...
threading.Thread(target=main).start()
该代码严重依赖于 sys.stdin
和 sys.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/