如何测试具有多个输入调用的循环?

Posted

技术标签:

【中文标题】如何测试具有多个输入调用的循环?【英文标题】:How can I test a loop with multiple input calls? 【发布时间】:2019-10-23 04:58:12 【问题描述】:

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

我已经在这里寻找了多个答案,但没有一个能够解决我的问题。我看到了参数化、模拟和猴子补丁的东西,但没有任何帮助。我想很多是因为我没有清楚地理解所做事情背后的概念,我无法适应我的问题。我看到了为此使用外部文件的建议,但我不会依赖它。我正在尝试使用 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

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

编辑

我在“if”中添加了一个 int(),正如 wim 在接受的答案中指出的那样,只是为了防止给未来的读者造成任何混淆。我假设演员阵容是可能的。

【问题讨论】:

【参考方案1】:

这里有两个问题,需要将输入转换成数字否则比较会失败,比较字符串和数字:usr_input &lt; 5。请注意,真正的input 永远不会返回数字,只会返回字符串。

一旦你清除了它,你就可以用一个可调用的东西对input进行monkeypatch,当调用它时可以返回不同的值:

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

【讨论】:

以上是关于如何测试具有多个输入调用的循环?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过phpunit对一个方法进行单元测试,该方法具有多个内部调用保护/私有方法?

如何从 ASP.NET 调用具有多个输入值的 MySQL 存储过程

如何使用多个具有相同名称的表单输入?

CUDA:并行化具有嵌套循环的函数调用的多个嵌套for循环

如何从 Matlab 调用具有多个输出的 C++ 函数?

Keras:具有多个参数的 Lambda 层函数