python - 如何使用 pytest 测试交互式 python 应用程序

标签 python unit-testing pytest python-unittest

我有这个函数定义:

def interactive_mode():
    parking_query = Query()

    while(True):
        query = input()
        if query == 'exit':
            return -1
        else:
            parking_query.process(query)

我需要使用 pytest 测试这个函数,当我的测试文件中的 input() 处于无限循环内时,如何模拟它?

此外,在模拟输入后,我需要从 stdout 捕获每个输入的输出,这可以在 pytest 中使用 capsys 来完成。

我尝试过做的事情:

1.

monkeypatch.setattr('sys.stdin', io.StringIO(query))

这会给出 EOF 错误,不起作用!

2.

from unittest.mock import Mock

mock_stdin = Mock()
mock_stdin.readline = Mock(io.StringIO(query))

monkeypatch.setattr('sys.stdin', io.StringIO(query))

当我运行pytest时无限卡住

我的测试功能:

def test_interactive_mode(capsys, monkeypatch):
    '''
        Tests the interactive_mode() method by mocking
        stdin using monkeypatch and reading stdout using capsys
    '''
    testcases = [
        {
            'input':  [
                        'input query'
                      ],
            'output': [
                        'expected output response to query'
                      ] 
        }
    ]

    for case in testcases:
        for i, query in enumerate(case['input']):
            with mock.patch.object(builtins, 'input', lambda : query):
                # mock_stdin = Mock()
                # mock_stdin.readline = Mock(io.StringIO(query))

                # monkeypatch.setattr('sys.stdin', io.StringIO(query))

                return_value = interactive_mode()

                if return_value == -1:
                    break

                captured = capsys.readouterr()

                assert captured.out == case['output'][i] + '\n'

最佳答案

找到了一种解决问题的奇特方法,可以达到目的,但不建议作为完美的解决方案!

def test_interactive_mode(capsys, monkeypatch):
    '''
        Tests the interactive_mode() method by mocking
        stdin using monkeypatch and reading stdout using capsys
    '''
    testcases = [
        {
            'input':  [
                        'input query'
                      ],
            'output': [
                        'expected output response to query'
                      ] 
        }
    ]

    for case in testcases:
        for i, query in enumerate(case['input']):
            with mock.patch('builtins.input', side_effect=[query, 'exit']):
                return_value = interactive_mode()

                if return_value == -1:
                    break

                captured = capsys.readouterr()

                assert captured.out == case['output'][i] + '\n'

关于python - 如何使用 pytest 测试交互式 python 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60694950/

相关文章:

java - Scala 中是否有等效的 junit 测试套件

unit-testing - 模拟使用箭头函数作为参数调用的方法

python - 如何使用 pytest 确认引发正确的异常

python - 可以重新加载导入的字典吗?

python - 通过 macports 安装 Py.test 时出错

python - 我如何知道在Python中添加多少个反斜杠

python - Pylint 错误消息 : "E1101: Module ' lxml. etree'没有 'strip_tags' 成员'”

javascript - 专门支持测试异步代码的 node.js 单元测试框架?

单独文件中的python字典

javascript - 在 Python 中处理 JSON 事件