Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 如何对结果基于while循环中包含的条件语句的函数进行单元测试_Python 3.x_Unit Testing_While Loop_Mocking_Pytest - Fatal编程技术网

Python 3.x 如何对结果基于while循环中包含的条件语句的函数进行单元测试

Python 3.x 如何对结果基于while循环中包含的条件语句的函数进行单元测试,python-3.x,unit-testing,while-loop,mocking,pytest,Python 3.x,Unit Testing,While Loop,Mocking,Pytest,我想知道什么是单元测试while循环的最佳方法,该循环仅在输入特定输入时才会中断(有关更多详细信息,请参阅代码)。我的测试实际上按照预期工作,并且没有正确地通过。然而,我觉得这是“黑客攻击”,并不是测试此类代码的最佳方式 目前,我必须通过模拟中断循环的用户输入来手动中断测试中的循环(有关更多详细信息,请参阅代码)。我已经尝试过在pytest中进行参数化,但是,只要我模拟一个没有中断循环的输入,测试就会卡在一个无限循环上。它永远不会到达下一个参数化值 正在测试的功能 测试功能 我根据我当前的代码得

我想知道什么是单元测试while循环的最佳方法,该循环仅在输入特定输入时才会中断(有关更多详细信息,请参阅代码)。我的测试实际上按照预期工作,并且没有正确地通过。然而,我觉得这是“黑客攻击”,并不是测试此类代码的最佳方式

目前,我必须通过模拟中断循环的用户输入来手动中断测试中的循环(有关更多详细信息,请参阅代码)。我已经尝试过在pytest中进行参数化,但是,只要我模拟一个没有中断循环的输入,测试就会卡在一个无限循环上。它永远不会到达下一个参数化值

正在测试的功能 测试功能 我根据我当前的代码得到我想要的结果。但是,我希望尽可能使用最佳实践,并将其应用于处理仅基于特定用户输入中断的while循环时的所有未来测试。

关于永远不会退出的“真实”无限循环:嵌入式系统上的进程有时会这样实现,并且仅当系统因断电或被操作系统杀死而关闭时才会终止。对于此类循环,典型的解决方案是将循环体提取到单独的函数/方法中

def main_loop():
    while True:
        main_body()
这样,通过将代码提取到
main\u body
,可以最大限度地增加可进行单元测试的代码量。显然,
main_loop
仍然不能进行单元测试,但可以在更高级别的测试中进行测试

显然,您的循环不是那种类型的,因为您有可能在不终止线程等的情况下离开循环。因此,我认为您测试该函数的方法在原则上是非常合理的

但是,有一些方法可以改进测试套件。举个例子:您作为示例展示的测试用例已经是一个复杂的测试,我建议从更基本的测试开始:

  • 测试数字1是否被接受
  • 测试数字4是否被接受
  • 测试数字0是否不被接受(顺序:0,1..4中的一个)
  • 测试数字5是否不被接受(顺序:5,1..4中的一个)

如果这些测试中的任何一个失败了,它将给你一个更直接的指示问题可能在哪里。这些测试尚未测试(与您的测试相反)的是,例程是否能够处理多个错误输入,以及提示和错误消息是否如预期的那样。但是,这些是单独的方面,因此将您的测试分为单独的测试是有意义的,每个方面一个测试。

您好,谢谢您的反馈!我应该补充一点,我使用参数化测试1到4,以便按照预期返回所有有效输入(此处不包括函数)。至于第3点和第4点,我测试0点和第5点的方式不是那么合理吗?比如使用副作用进行两次调用,然后查看print语句是否只调用了两次?换句话说,单独测试每个变量是否总是比我这样做更好?我觉得这比用两个单独的测试来检查两个无效值看起来更“干净”。如果我不清楚,很抱歉:用一个测试(和你一样)来测试可以给出多个错误输入是完全可以的。我的意思是,这个测试理想地遵循一些检查代码更基本属性的测试。例如,如果检查1是否为可接受输入的测试失败,则更复杂的测试也可能失败。然后,当您查看测试结果时,您将意识到基本测试失败,您可能会立即看到问题。如果您只有复杂的测试,您可能无法立即看到导致失败的原因。
@mock.patch('realestate.app.user_inputs.print')
# The 1 is used to break the loop otherwise the test never ends!
@mock.patch('realestate.app.user_inputs.input', side_effect=[0, 5, 1])
def test_export_options_invalid_integer(mock_choice, mock_print):
    user_inputs.export_options()

    # Best way I could think of to test bad inputs. Anything that is less than 1 or greater than 4 will fail the test.
    # Make sure I call the correct print function
    mock_print.assert_called_with("\nNot a valid selection\n")
    # Make sure I call the correct print function twice
    assert mock_print.call_count == 2
def main_loop():
    while True:
        main_body()