Python 在循环中使用模拟库进行用户输入测试
Python testing using mock library for user input in a loop
我正在尝试使用模拟库来测试一段代码。在此代码中,用户原始输入在 for 循环中被接受,如下所示。我已经编写了测试用例 test_apple_record
,它可以为托盘编号提供单个用户输入值。
但是,对于 for 循环中的每次迭代,它只采用与预期相同的值 (5)。
问题是:如何为每次迭代提供不同的值?例如,对于 i=0、1 和 2,托盘编号的具体值分别为 5、6 和 7。
class SomeClass(unittest.TestCase):
def apple_counter(self):
apple_record = {}
for i in range(3):
apple_tray = input("enter tray number:")
apple_record[apple_tray] = (i+1)*10
print("i=%d, apple_record=%s"%(i, apple_record))
def test_apple_record(self):
with mock.patch('builtins.input', return_value='5'):
self.apple_counter()
您可以将 side_effect
参数与可迭代对象一起使用以提供 return 值:
with mock.patch('builtins.input', side_effect=[5, 6, 7]):
self.apple_counter()
参见 docs:
If side_effect is an iterable then each call to the mock will return the next value from the iterable.
原来我是在重新发明轮子。请改用 side_effect
参数。无论如何,在这里留下一个修改版本,以防有人想做一些花哨的事情。
要使用不同的函数,请使用 patch
的 new_callable
关键字参数
with mock.patch('builtins.input', new_callable=lambda *x: random.randrange(0,10)):
do_stuff()
然而,这意味着值是完全随机的,这对于测试来说是不可取的,因为这意味着测试不是确定性的,可能失败或并非完全偶然。此外,您可能希望 input() 函数发出生成的非随机值,例如一系列命令或类似内容。为此,我认为最简单的方法是生成器函数。
def input_generator(): # generate squares as an example
a = 0
while True:
yield a**2
a += 1
g = input_generator()
with mock.patch('builtins.input', lambda *x: next(g)):
do_stuff()
我正在尝试使用模拟库来测试一段代码。在此代码中,用户原始输入在 for 循环中被接受,如下所示。我已经编写了测试用例 test_apple_record
,它可以为托盘编号提供单个用户输入值。
但是,对于 for 循环中的每次迭代,它只采用与预期相同的值 (5)。
问题是:如何为每次迭代提供不同的值?例如,对于 i=0、1 和 2,托盘编号的具体值分别为 5、6 和 7。
class SomeClass(unittest.TestCase):
def apple_counter(self):
apple_record = {}
for i in range(3):
apple_tray = input("enter tray number:")
apple_record[apple_tray] = (i+1)*10
print("i=%d, apple_record=%s"%(i, apple_record))
def test_apple_record(self):
with mock.patch('builtins.input', return_value='5'):
self.apple_counter()
您可以将 side_effect
参数与可迭代对象一起使用以提供 return 值:
with mock.patch('builtins.input', side_effect=[5, 6, 7]):
self.apple_counter()
参见 docs:
If side_effect is an iterable then each call to the mock will return the next value from the iterable.
原来我是在重新发明轮子。请改用 side_effect
参数。无论如何,在这里留下一个修改版本,以防有人想做一些花哨的事情。
要使用不同的函数,请使用 patch
new_callable
关键字参数
with mock.patch('builtins.input', new_callable=lambda *x: random.randrange(0,10)):
do_stuff()
然而,这意味着值是完全随机的,这对于测试来说是不可取的,因为这意味着测试不是确定性的,可能失败或并非完全偶然。此外,您可能希望 input() 函数发出生成的非随机值,例如一系列命令或类似内容。为此,我认为最简单的方法是生成器函数。
def input_generator(): # generate squares as an example
a = 0
while True:
yield a**2
a += 1
g = input_generator()
with mock.patch('builtins.input', lambda *x: next(g)):
do_stuff()