【发布时间】:2020-02-18 01:02:12
【问题描述】:
我正在使用 pytest 中的 monkeypatch 夹具,试图模拟终端窗口的当前大小。
import os
import pytest
def get_terminal_size():
terminal_size = os.popen('stty size', 'r').read()
return terminal_size
def test_get_terminal_size(monkeypatch):
# The get_terminal_size() function will return a string 'height width\n'
def mock_size():
return '10 20\n'
monkeypatch.setattr(os.popen('stty size', 'r'), 'read', mock_size)
assert get_terminal_size() == '10 20\n'
当我运行 pytest 时出现断言错误:
__________________________________________________________________ test_get_terminal_size __________________________________________________________________
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f5bf1ec0cf8>
def test_get_terminal_size(monkeypatch):
# The get_terminal_size() function will return a string 'height width\n'
def mock_size():
return '10 20\n'
monkeypatch.setattr(os.popen('stty size', 'r'), 'read', mock_size)
> assert get_terminal_size() == '10 20\n'
E AssertionError: assert '' == '10 20\n'
E + 10 20
test_monkeypatch.py:15: AssertionError
所以看起来它没有设置 mock_size。我试过遵循pytest documentation中的模式
关于让它工作的任何建议?
提前致谢!
更新: 正如 Kent Shikama 在下面的答案中指出的那样,对于我尝试捕获输出的方式,我需要使用 -s 标志来关闭 pytest 捕获。
但是随着对 popen 用法的进一步研究,特别是从使用 os.popen 到 subprocess.Popen 的迁移,请参阅 here,以及来自 S.O. post 关于“如何伪造 Popen”的一些帮助,我已经想出一个解决方案。
这是新设置:
# \mokeypatch_popen.py
from subprocess import Popen
def get_terminal_size():
terminal_size = Popen('stty size', shell=True)
return terminal_size
测试功能:
# \test_monkeypatch.py
import pytest
import monkeypatch_popen
def test_get_terminal_size(monkeypatch):
# The get_terminal_size() function will return a string 'height width\n'
def mock_terminal_size(cmd, **kwargs):
return '10 20\n'
monkeypatch.setattr(m_patch, 'Popen' , mock_terminal_size)
assert m_patch.get_terminal_size() == '10 20\n'
起初对我来说并不明显的是 mock_terminal_size 函数将处理它正在模拟的 Popen 方法的参数,因此它必须接受 Popen 在原始函数中使用的参数。我本可以专门将 shell 参数添加到 mock_terminal_size,但由于 Popen 接受一长串 kwarg,所以我有点模棱两可。
现在,当我运行 pytest 并且不需要 -s 标志时,这会通过,因为我不再尝试捕获输出,而是模拟 Popen 方法的执行。
【问题讨论】:
标签: python python-3.x pytest