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

标签 python-3.x unit-testing while-loop mocking pytest

我想知道对 while 循环进行单元测试的最佳方法是什么,该循环仅在输入特定输入时才会中断(有关更多详细信息,请参阅代码)。我的测试实际上按预期工作并且正确失败。然而,我觉得它是“拼凑在一起”的,并不是测试此类代码的最佳方法。

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

正在测试的功能

def export_options():
    while True:
        try:
            choice = int(input("\nPlease make a selection"))
            if choice in range(1, 5):
                return choice
            else:
                 # I want to test this line when the input is bad
                print("\nNot a valid selection\n")  
        except ValueError as err:
            print("Please enter an integer")

测试函数

@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

我根据当前的代码得到了我想要的结果。不过,我希望尽可能使用最佳实践,并将其应用到处理仅根据特定用户输入而中断的 while 循环时的所有 future 测试。

最佳答案

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

def main_loop():
    while True:
        main_body()

这样,您就可以通过将代码提取到 main_body 来最大化可进行单元测试的代码量。显然,main_loop仍然无法进行单元测试,但可以在更高级别的测试中进行测试。

显然,您的循环不是那种循环,因为您有可能在不杀死线程等的情况下离开循环。因此,我认为您测试该功能的方法原则上是相当合理的。

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

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

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

关于python-3.x - 如何对结果基于 while 循环中包含的条件语句的函数进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56365093/

相关文章:

python - redis/rq worker 在 python3 上中断

python - PEP-526 与类变量的文档字符串不兼容?

python - 运行程序一分钟然后暂停一分钟的最简单方法是什么

Java 网络阻塞方法和 while 循环

python - 在Python中,While循环具有多个条件,直到满足一个条件

python - 字典内棘手的列表操作

python - Matplotlib 随着时间的推移绘制旧点消失的点

iphone - Objective C - 如何使用 OC Mock?

python - 单元测试 : increase module's verbosity when tested

node.js - Nodejs - Mocha、Chai 多重异步测试