【问题标题】:Getting started with unit testing for functions without return values开始对没有返回值的函数进行单元测试
【发布时间】:2015-05-15 12:17:31
【问题描述】:

我有一个基于函数的程序,它在函数内部接受用户输入,而不是函数之前的参数:例如,假设我的函数是

def my_function():
    a = input("a: ")
    b = input("b: ")
    print(a+b)

据我目前对单元测试的了解,这样的函数比像这样工作的函数更难单元测试:

def another_function(a,b):
    return(a+b)

那么,例如,我该如何测试一个看起来像 my_function 的函数呢?感觉好像只要输入不正确的输入并检查错误就可以很容易地手动测试,但是我必须编写一个测试套件来自动测试我的所有功能。

【问题讨论】:

  • 您可以修补input 以提供您想要的任何值,或者在函数定义中设置input=input 并手动注入一些东西来替换内置的input(参见例如this code I用后一种方法测试)。
  • 啊,好吧,所以我可以创建一个预定义变量“a”的测试方法/函数,以便在测试套件中使用它?例如,它可以断言 print("papajohn") 是否等于 my_function(),其中“papa”为 a,“john”为 b?
  • 不是真的,你还需要在你的情况下修补print,因为你的函数不会返回任何东西(或者,更好,将它们重组为returnprint 其他地方)。你需要有一个模拟 stdout 然后确保你期望的文本被传递给它。
  • 好的,故事的寓意是你不能真正测试没有返回值的函数?
  • 当然要困难得多!至少在 Python 3 中,print 是一个函数,它比 Python 2 更轻松。

标签: python unit-testing python-3.x


【解决方案1】:

鉴于您的函数输入来自input,输出到print,您必须“模拟”这两个函数来测试my_function。例如,使用简单的手动模拟:

def my_function(input=input, print=print):
    a = input("a: ")
    b = input("b: ")
    print(a+b)

if __name__ == '__main__':
    inputs = ['hello', 'world']
    printed = []

    def mock_input(prompt):
        return inputs.pop(0)

    def mock_print(text):
        printed.append(text)

    my_function(mock_input, mock_print)
    assert len(inputs) == 0, 'not all input used'
    assert len(printed) == 1, '{} items printed'.format(len(printed))
    assert printed[0] == 'helloworld'

当您将其与以下内容进行比较时:

assert my_function('hello', 'world') == 'helloworld'

你会明白为什么后者更受欢迎!

您还可以使用适当的模拟库来更整洁地执行此操作,而无需将函数作为参数提供;参见例如How to supply stdin, files and environment variable inputs to Python unit tests?.

【讨论】:

  • 是的,我明白了。也许我应该在我的主程序中稍微重写我的函数,以便它们返回一个我可以用于单元测试的值,因为那个小程序需要那么多代码去测试。我的程序比这要长得多,并且在此过程中有几个输入,所以也许这会更容易..非常感谢您的帮助!
猜你喜欢
  • 2010-12-09
  • 2013-04-03
  • 1970-01-01
  • 2022-10-20
  • 2022-12-18
  • 2020-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多