使用多个输入调用的功能如何有效地测试单元



我有一个按预期工作的单元测试,但是我觉得这不是测试用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

最新更新