如何测试具有多个输入呼叫的循环?

时间:2019-06-07 16:57:56

标签: python-3.x loops testing mocking pytest

我正在尝试测试依赖于多个用户输入的函数以返回一些值。

我已经在这里寻找多个未解决的问题,但没有一个能够解决我的问题。我看到了带有参数化,模拟和猴子补丁的东西,但是没有帮助。我认为很多原因是因为我不清楚所执行的操作背后的概念,并且无法适应自己的问题。我看到了为此使用外部文件的建议,但我不会依赖于此。我正在尝试使用pytest和python 3.7.3

我要测试的功能是这样的

def function():
    usr_input = input('please enter a number: ')
    while True:
        if int(usr_input) < 5:
            usr_input = input('please, enter a value less then 5: ')
        else:
            break
    return usr_input

我想知道当插入的值无效时如何传递两个输入值来测试功能。示例:发送值6和2,确定期望值2,然后通过测试。我的其他测试如下:

def test_input(monkeypatch):
    monkeypatch.setattr('builtins.input', lambda x: 6)
    test = function()
    assert test == 2

但是,在这种情况下,它们会循环。只能使用参数化或其他简单代码来做到这一点?

编辑

正如wim在接受的答案中指出的那样,我在“ if”中添加了一个int(),目的是防止对以后的读者造成任何混乱。我假设可以进行转换。

1 个答案:

答案 0 :(得分:0)

这里有两个问题,您需要将输入转换为数字,否则比较将失败,将字符串与数字进行比较:usr_input < 5。请注意,实数input将永远不会返回数字,只会返回一个字符串。

一旦您清除了这些内容,就可以用可调用的猴子input进行修补,该可调用的对象在被调用时可以返回不同的值:

def fake_input(the_prompt):
    prompt_to_return_val = {
        'please enter a number: ': '6',
        'please, enter a value less then 5: ': '2',
    }
    val = prompt_to_return_val[the_prompt]
    return val

def test_input(monkeypatch):
    monkeypatch.setattr('builtins.input', fake_input)
    test = function()
    assert test == 2

如果安装插件pytest-mock,则可以使用模拟API更轻松地完成此操作:

def test_input(mocker):
    mocker.patch('builtins.input', side_effect=["6", "2"])
    test = function()
    assert test == 2