我想知道什么是最好的单元测试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循环时,将其应用于以后的所有测试。
答案 0 :(得分:1)
关于永不退出的“真实”无限循环:嵌入式系统上的进程有时是这样实现的,并且仅在系统因关机或被操作系统杀死而终止时才会终止。对于此类循环,典型的解决方案是将循环主体提取到单独的函数/方法中。
def main_loop():
while True:
main_body()
这样,您通过将代码提取到main_body
中来最大化了可以进行单元测试的代码量。显然,main_loop
仍然不能进行单元测试,但是可以在更高级别的测试中进行测试。
很显然,您的循环不是那种类型,因为您可以退出循环而不会杀死线程等。因此,我认为您原则上测试该功能的方法是正确的。
但是,有一些方法可以改善测试套件。举个例子:作为例子显示的测试用例已经是一个复杂的测试,我建议从更基础的测试开始:
如果这些测试中的任何一个失败,它将为您提供更直接的指示,表明问题可能出在哪里。这些测试尚未测试的内容(与您的测试相反)是,该例程是否将能够处理多个错误的输入,以及提示和错误消息是否符合预期。但是,这些是各个方面,因此将您的测试分为多个单独的测试是有意义的。