将不同的 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!
我想用 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!