Python单元测试潜在的无限循环
我有一个Python函数,如果传入不好的数据,它会陷入无限循环。我想写一个单元测试,确认这个函数能优雅地处理这些不好的参数。问题是,如果它没有检测到这些不好的参数,就不会返回结果。
用线程来写这样的测试可以吗?
import threading, unittest
import mymodule
class CallSuspectFunctionThread(threading.Thread):
def __init__(self, func, *args):
self.func = func
self.args = args
super(CallSuspectFunctionThread, self).__init__()
def run(self):
self.func(*self.args)
class TestNoInfiniteLoop(unittest.TestCase):
def test_no_infinite_loop(self):
myobj = mymodule.MyObject()
bad_args = (-1,0)
test_thread = CallSuspectFunctionThread(mybj.func_to_test, *bad_args)
test_thread.daemon = True
test_thread.start()
# fail if func doesn't return after 8 seconds
for i in range(32):
test_thread.join(0.25)
if not test_thread.is_alive():
return
self.fail("function doesn't return")
我看到的唯一问题是,如果测试失败了,我就会有一个额外的线程在那儿,可能会消耗CPU和内存资源,而其他测试还在执行。另一方面,我已经修复了代码,这里出现问题的可能性非常小,所以我不知道是否真的有必要包含这个测试。
6 个回答
1
我建议加一个测试来检查是否有无限循环,因为如果在测试过程中程序卡住了,至少你能在正式上线之前发现这个问题。如果发生这种情况的可能性很小(就像你说的那样),那我就不太担心测试写得复杂,但我还是会对代码进行测试。
12
你可以添加一个超时装饰器。把测试用例的逻辑和超时机制分开是个好主意。这样做会让你的代码更容易读懂,也更方便维护。
可以查看这个链接:http://pypi.python.org/pypi/timeout。
-1
你根本无法测试这个问题。假设另一个线程只是“慢”,或者更糟糕的是“活锁”(也就是在等待一个共享资源),那么你做出的任何假设都可能与现实不符。
你不能随便说“以前总是1.5秒就结束,但现在似乎要久一点。我试试2秒,看能不能通过。” 这样是不可接受的。
你必须确保所有的循环都能在任何时候结束。所有的循环。
如果做不到这一点,那就是设计得太糟糕,根本不应该被使用。
如果你不能防止出现无限循环,那你的设计就还没完成。
这不是可以通过测试来解决的问题。