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

Passing different raw_input to a function being tested in Python

我想用 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

为了实现这一点,您需要将 raw_input 替换为一个函数,该函数在多次调用时 returns 会发生不同的事情,例如像这样的:

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,在 finally 代码中恢复 raw_input。不过还有更好的方法:使用所谓的上下文管理器。 captured_out 是一个例子,它重定向一些代码的输出并保证恢复原始输出目标。以此为练习,对理解这个技巧很有帮助。
  • 顺序颠倒了,因为pop从后面删除了元素。您可以先将序列提供给 reversed,但这会使代码的可读性和可理解性更差。将其包装到上下文管理器中会隐藏这些细节。
  • 别忘了升级到 Python 3!