gpt4 book ai didi

python - pytest Monkeypatch 终端大小

转载 作者:行者123 更新时间:2023-12-01 06:23:16 24 4
gpt4 key购买 nike

我正在 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 在下面的答案中指出的那样,对于我 try catch 输出的方式,我需要使用 -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 接受一长串 kwargs,所以我有点模糊。

现在,当我运行 pytest 时,这个问题就过去了,并且 -s 标志不是必需的,因为我不再 try catch 输出,而是模拟 Popen 方法的执行。

最佳答案

首先,您需要使用 -s 标志运行 pytest,否则 stty 将被捕获。然后你应该得到你可能期望的断言错误,如下所示:

>       assert get_terminal_size() == '10 20\n'
E AssertionError: assert '24 80\n' == '10 20\n'
E - 24 80
E + 10 20

听起来您想模拟流上的读取方法,使其始终运行“10 20”。通常你会做类似的事情

from io import TextIOWrapper
monkeypatch.setattr(TextIOWrapper, 'read', mock_size)

但不幸的是你不能模拟内置对象。您可以尝试类似 forbiddenfruit来克服这个问题,但感觉你可能想要改变你的方法。

关于python - pytest Monkeypatch 终端大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60272369/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com