我有一个不应该挂起的功能。具体来说,它会检测导致挂起的条件并引发错误。简化,我的功能类似于这个:
def chew_repeated_leading_characters(string: str, leader: str):
if len(leader) == 0:
# Without this, will hang on empty string
raise ValueError('leader cannot be empty')
while True:
if string.startswith(leader):
string = string[len(leader):]
else:
break
return string
我想在pytest
中编写单元测试以确保此行为。我知道如何断言测试应该引发异常。但是,在这种情况下,如果测试失败,它实际上不会失败;整个测试设备都挂了。
如何在无限循环中生成测试失败?
答案 0 :(得分:2)
这种断言不存在。 “无无限循环”断言将成为values
的解决方案,事实证明它没有。
您应该检查是否发生在之后发生了一个事件,如果发生了,则会失败。如果您的函数在该raise子句之后使用副作用,那么最好检查该副作用,而不是向测试添加任意超时。
例如,这种方法:
side_effect()
可以通过模拟string
来测试,并使其在通话时触发失败。
超时应该被用作最后的解决方案。
编辑:关于你的代码,很容易做到没有超时 - 传递一个模拟startswith()
,在调用from mock import Mock
...
string_mock = Mock()
string.startswith.side_effect = AssertionError('This will hang.')
leader_mock = Mock()
leader.__len__ = lambda self: 0
chew_repeated_leading_characters(string_mock, leader_mock)
时触发失败:
{{1}}
答案 1 :(得分:1)
在数学上不可能断言这一点。请参阅the Halting Problem。
然而,你可以做的是设置一个闹钟,在经过一段时间后停止运行。如果测试仍在运行,则表示失败。
无需查看任何代码,很难提出更明确的建议。
答案 2 :(得分:1)
虽然上述答案是正确的,但在一般意义上不可能这样做,但您可以使用类似https://pypi.org/project/pytest-timeout/的内容来实现解决方案。