如何测试内部有两个或多个 input() 的函数?
How to test function, that has two or more input()'s inside?
我需要测试一些 python 3 代码,但我在测试函数时遇到了一些 input() 的问题。
示例:
def two_answers():
if input("Input 'go' to proceed") != "go":
return two_answers()
else:
while input("Input 'bananas' to proceed") != "bananas":
print("What?!")
print("You've just gone bananas!")
对于只有一个输入的函数,我使用:
def test_some_function(self):
codefile.input = lambda x: 'u'
codefile.some_function() . . . .
然后:
def teardown_method(self, method):
codefile.input = input
还原输入。
但是这里不行。求助!
你想要的是模拟用户输入。
您必须使用 unittest.mock 并修补 input
函数。
参见Quick Guide。
这是我的解决方案:
class SimulatedInput:
def __init__(self,*args):
self.args = iter(args)
def __call__(self,x):
try:
return next(self.args)
except StopIteration:
raise Exception("No more input")
然后你就可以像以前一样使用它了:
def test_some_function(self):
codefile.input = SimulatedInput("u","v")
codefile.some_function() . . . .
一个没有依赖项的简约示例。随心所欲地使用它来扩展它:
import sys
import io
def two_answers():
if input("Input 'go' to proceed") != "go":
return two_answers()
else:
while input("Input 'bananas' to proceed") != "bananas":
print("What?!")
print("You've just gone bananas!")
def wrapper():
lines = ["go", "bananas"]
def fake_input(*args, **kwargs):
return lines.pop(0)
global input
real_input = input
input = fake_input
two_answers()
input = real_input
wrapper()
我会将输入包装到一个函数中。
def input_wrap(prompt):
return input(prompt)
然后就可以注射了
def two_answers(input_func):
if input_func('...') != 'go':
return two_answers(input_func)
...
现在当你想测试它时,你可以注入假的或模拟的:
def test_two_answers(self):
fake_input = mock.MagicMock()
fake_input.side_effect = ['go', 'foo', 'bananas']
two_answers(fake_input) # no assertion for needed since there's no return value
稍后在执行 two_answers 的代码中,您可以这样称呼它:
two_answers(input_wrap)
我需要测试一些 python 3 代码,但我在测试函数时遇到了一些 input() 的问题。
示例:
def two_answers():
if input("Input 'go' to proceed") != "go":
return two_answers()
else:
while input("Input 'bananas' to proceed") != "bananas":
print("What?!")
print("You've just gone bananas!")
对于只有一个输入的函数,我使用:
def test_some_function(self):
codefile.input = lambda x: 'u'
codefile.some_function() . . . .
然后:
def teardown_method(self, method):
codefile.input = input
还原输入。
但是这里不行。求助!
你想要的是模拟用户输入。
您必须使用 unittest.mock 并修补 input
函数。
参见Quick Guide。
这是我的解决方案:
class SimulatedInput:
def __init__(self,*args):
self.args = iter(args)
def __call__(self,x):
try:
return next(self.args)
except StopIteration:
raise Exception("No more input")
然后你就可以像以前一样使用它了:
def test_some_function(self):
codefile.input = SimulatedInput("u","v")
codefile.some_function() . . . .
一个没有依赖项的简约示例。随心所欲地使用它来扩展它:
import sys
import io
def two_answers():
if input("Input 'go' to proceed") != "go":
return two_answers()
else:
while input("Input 'bananas' to proceed") != "bananas":
print("What?!")
print("You've just gone bananas!")
def wrapper():
lines = ["go", "bananas"]
def fake_input(*args, **kwargs):
return lines.pop(0)
global input
real_input = input
input = fake_input
two_answers()
input = real_input
wrapper()
我会将输入包装到一个函数中。
def input_wrap(prompt):
return input(prompt)
然后就可以注射了
def two_answers(input_func):
if input_func('...') != 'go':
return two_answers(input_func)
...
现在当你想测试它时,你可以注入假的或模拟的:
def test_two_answers(self):
fake_input = mock.MagicMock()
fake_input.side_effect = ['go', 'foo', 'bananas']
two_answers(fake_input) # no assertion for needed since there's no return value
稍后在执行 two_answers 的代码中,您可以这样称呼它:
two_answers(input_wrap)