我有一个按预期工作的单元测试,但是我觉得这不是测试用pytest测试多个输入的最佳方法。它肯定违反了干燥原则。我认为有一种更好的方法可以解决这个问题,但我不知道什么。我也不确定该如何处理模拟。它没有使用,但必须在那里(请参阅下面代码中的函数中的'mock_choice'参数(。
我认为也许通过通话循环会起作用,但这无效。除了使用side_effects并致电四次测试以确保我按照我的预期获得返回值,我真的找不到其他方式。
函数要测试
def export_options():
while True:
try:
choice = int(input("nPlease make a selection"))
if choice in ([option for option in range(1, 5)]):
return choice # This what I'm testing
else:
print("nNot a valid selectionn")
except ValueError as err:
print("Please enter an integer")
测试功能
@mock.patch('realestate.app.user_inputs.input', side_effect=[1, 2, 3, 4])
def test_export_options_valid_choice(mock_choice): # mock_choice needs to be here but isn't used!
export_option = user_inputs.export_options()
assert export_option == 1
export_option = user_inputs.export_options()
assert export_option == 2
export_option = user_inputs.export_options()
assert export_option == 3
export_option = user_inputs.export_options()
assert export_option == 4
测试有效。当功能返回1到4之间的所有值时,它通过。但是,由于代码非常重复,我想知道是否有更好的方法来测试多个输入调用,因为我想将其应用于将来的测试。<<<<<<<<<<<<<</p>
您可以使用for loop来避免重复代码。
@mock.patch('realestate.app.user_inputs.input')
def test_export_options_valid_choice(self, mock_choice):
for response in [1, 2, 3, 4]:
with self.subTest(response=response)
mock_choice.return_value = response
export_option = user_inputs.export_options()
self.assertEqual(export_option, response)
# Not in original version, but other tests might need it.
mock_choice.assert_called_once_with("nPlease make a selection")
mock_choice.reset_mock()
子测试上下文管理器将告诉您哪个输入失败。
是使用UNITSEST模块进行子测试的唯一方法?我知道pytest不支持子测试,但我希望有类似类型的黑客。
您肯定可以不使用子测试而循环循环,但是您可能很难告诉哪个输入失败。更一般而言,您可以为每个测试调用一个通用的辅助功能,而不是循环。
特别是对于pytest,您可以使用@pytest.mark.parametrize
装饰器来自动化此。
@pytest.mark.parametrize('response', [1, 2, 3, 4])
@mock.patch('realestate.app.user_inputs.input')
def test_export_options_valid_choice(mock_choice, response):
mock_choice.return_value = response
export_option = user_inputs.export_options()
assert export_option == response