python - 测试需要用户输入的 Python 函数()

标签 python testing pytest

我想测试以下功能:

def get_inputs():
    str_from_user = input()
    list_of_marks = []
    while str_from_user != "exit":
        list_of_marks.append('!')
        str_from_user = input()
    return list_of_marks

有没有办法测试多个场景? 像这样的东西(但只有这样有效):

def test_get_inputs():
    assert get_inputs(){"hey", "coco", "milo", "exit"} == "!!!"
    assert get_inputs(){"exit"} == ""
    assert get_inputs(){"horses have long faces", "exit} == "!"

最佳答案

没有明显的方法来测试当前编写的函数,因为您正在从标准输入读取。这是一个副作用,使您的函数不 pure并且很难测试。换句话说,输入来自程序外部,因此您无法控制它。

您应该以一种易于在程序内提供输入和检查输出的方式重写函数。您可以通过传递一个函数作为获取输入的方式来执行此操作,而不是始终使用 input() 。然后,为了进行测试,您可以在已知输入列表上创建一个简单的迭代器对象并传递其 __next__方法作为输入函数。

以下是如何完成此操作的示例:

def get_inputs(input_function):
    str_from_user = input_function()
    list_of_marks = []
    while str_from_user != "exit":
        list_of_marks.append('!')
        str_from_user = input_function()
    return list_of_marks

def test_get_inputs():
    input_func_one   = iter(["hey", "coco", "milo", "exit"]).__next__
    input_func_two   = iter(["exit"]).__next__
    input_func_three = iter(["horses have long faces", "exit"]).__next__
    assert get_inputs(input_func_one) == ['!', '!', '!']
    assert get_inputs(input_func_two) == []
    assert get_inputs(input_func_three) == ['!']

另一种选择,如@chepner建议的在上面的注释中,将向函数传递一个类似文件的对象,可以使用 io 轻松模拟该对象。模块具有 BytesIOStringIO 。但在这种情况下要小心,因为 input()删除尾随换行符,但是 StringIO.readline()没有。

from io import StringIO

def get_inputs(input_file):
    str_from_user = input_file.readline().rstrip()
    list_of_marks = []
    while str_from_user != "exit":
        list_of_marks.append('!')
        str_from_user = input_file.readline().rstrip()
    return list_of_marks

def test_get_inputs():
    assert get_inputs(StringIO("hey\ncoco\nmilo\nexit\n")) == ['!', '!', '!']
    assert get_inputs(StringIO("exit\n")) == []
    assert get_inputs(StringIO("horses have long faces\nexit\n")) == ['!']

您还可以调整第一种情况(传递输入函数)以使用 StringIO只需传递 StringIO("...").readline作为函数。


现在您有了一个易于测试的函数,您可以编写一个简单的包装器来使用该函数并使用标准输入:

# If using an input function
def get_inputs_from_stdin():
    return get_inputs(input)

# If using a file-like object
import sys

def get_inputs_from_stdin():
    return get_inputs(sys.stdin)

关于python - 测试需要用户输入的 Python 函数(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73038444/

相关文章:

java - 在linux中模拟 "faster time"

python - 在 python 应用程序中集成 pytest(提供 fixture )

python - 不使用 pytest no-capture 时运行子进程失败

python - 在使用 Python、Pyro 和 pytest 的测试框架上记录输入和输出

python - "-inf "在python中是什么意思?

java - 使用 Gradle 构建 Python 应用程序

javascript - 断言错误 : expected { status: 'SUCCESS' , 数据 : [] } to equal { Object (status, 数据)}

python - py.test 中如何执行常见的设置和清除工作?

python - 如何在 pygame 中生成多个敌人

python - 为什么我无法执行存储在环境变量中的 shellcode?