我正在使用python
框架unittest
。是否有可能通过框架的能力指定测试超时?如果不是,是否可以优雅地为所有测试指定timeout
,为某些单独的测试指定每个测试的私有值?
我想为所有测试定义一个global timeout
(默认情况下它们将使用它),并且可能需要很长时间才能进行一些测试的超时。
答案 0 :(得分:18)
据我所知unittest
不包含对测试超时的任何支持。
您可以从PyPI尝试timeout-decorator
库。在各个测试中应用装饰器,如果它们花费的时间太长就会终止它们:
import timeout_decorator
class TestCaseWithTimeouts(unittest.TestCase):
# ... whatever ...
@timeout_decorator.timeout(LOCAL_TIMEOUT)
def test_that_can_take_too_long(self):
sleep(float('inf'))
# ... whatever else ...
要创建全局超时,您可以替换呼叫
unittest.main()
与
timeout_decorator.timeout(GLOBAL_TIMEOUT)(unittest.main)()
答案 1 :(得分:4)
我使用unittest
keyowrd based on this answer构建了with
超时解决方案。
此方法也使用signal
,因此它可能仅在* nix系统上有效(我只在我的Ubuntu 16.04环境中运行它。)
TestTimeout
例外:import signal ... class TestTimeout(Exception): pass
test_timeout
,它将处理with
块:class test_timeout: def __init__(self, seconds, error_message=None): if error_message is None: error_message = 'test timed out after {}s.'.format(seconds) self.seconds = seconds self.error_message = error_message def handle_timeout(self, signum, frame): raise TestTimeout(self.error_message) def __enter__(self): signal.signal(signal.SIGALRM, self.handle_timeout) signal.alarm(self.seconds) def __exit__(self, exc_type, exc_val, exc_tb): signal.alarm(0)
with test_timeout()
块:def test_foo(self): with test_timeout(5): # test has 5 seconds to complete ... foo unit test code ...
使用这种方法,由于引发TestTimeout异常,超时测试将导致错误。
或者,您可以将with test_timeout()
块包装在try: except TestTimeout:
块中,并以更细的粒度处理异常(例如,跳过测试而不是错误)。