将不同的raw_input传递给Python中正在测试的函数

时间:2018-01-14 17:55:33

标签: python python-2.7 python-unittest

我想用unittest测试Python(2.7)中使用不同raw_input的函数。

我怎样才能做到这一点?

功能(在模块fc中):

def main():
    name            = raw_input("name: ").lower()
    surname         = raw_input("surname: ").lower()
    birth_date    = raw_input("Birth date (dd/mm/yyyy): ").lower()
    city          = raw_input("city: ").lower()
    sex           = raw_input("sex (m/f): ").lower()
    #other tasks...

测试功能:

import fc
import unittest

class test_main_fc(unittest.TestCase):

    def test_main(self):
        #how can I give to main the parameters that will ask?
        self.assertEqual(fc.main(), 'rssmra80a01l781k')             

if __name__ == '__main__':  
    unittest.main()

我能找到的解决方案this适用于一次传递的1个输入。我想知道如何将不同的值传递给main函数。

此功能仅适用于raw_input所请求的1个值,在本例中为name

class test_main_fc(unittest.TestCase):

    def test_fc_output(self):

        original_raw_input = __builtins__.raw_input
        __builtins__.raw_input = lambda _: 'mario'

        #capturing the output
        with captured_output() as (out, err):
            fc.main()
            output = out.getvalue().strip()

        self.assertEqual(output, 'rssmra80a01l781k')

        __builtins__.raw_input = original_raw_input

1 个答案:

答案 0 :(得分:1)

为了实现这一点,您需要将raw_input替换为多次调用时返回不同内容的函数,例如像这样:

answers = [1, 2, 4]
fake_input = answers.pop
# 4
print(fake_input())
# 2
print(fake_input())
# 1
print(fake_input())
# raise IndexError
print(fake_input())

您安装此功能类似于现有功能:

# replace raw_input
original_raw_input = __builtins__.raw_input
__builtins__.raw_input = ['input', 'fake', 'my'].pop
# ... code that uses raw_input
print raw_input()
print raw_input()
print raw_input()
# restore raw_input
__builtins__.raw_input = original_raw_input

一些注意事项:

  • 我不知道为什么原作者使用__builtins__.raw_input而不只是分配给raw_input(当然需要在函数中将其声明为global raw_input)。如果有任何不同,我没有尝试过。
  • 在测试中,如果输出不符合预期,则原始raw_input不会恢复!虽然这在测试中可以接受,但它仍然是一个错误。最简单的方法是使用try ... finally,在raw_input代码中恢复finally。但是有一种更好的方法:使用所谓的上下文管理器。 captured_out是一个示例,它重定向某些代码的输出并确保恢复原始输出目标。以此为锻炼,理解这种技术非常有用。
  • 订单相反,因为pop从后面删除了元素。您可以先将序列提供给reversed,但这会使代码更难以理解和理解。将它包装到上下文管理器中会隐藏这些细节。
  • 不要忘记升级到Python 3!