如何为python unittest指定测试超时?
我正在使用如何为python unittest指定测试超时?,python,unit-testing,timeout,Python,Unit Testing,Timeout,我正在使用pythonframeworkunittest。是否可以通过框架的能力指定测试超时?如果否,是否可以为所有测试指定一个超时,并为一些单独的测试为每个测试指定一个私有值? 我想为所有测试定义一个全局超时(默认情况下他们会使用它),并为一些可能需要很长时间的测试定义一个超时。据我所知,不包含任何对测试超时的支持 您可以尝试使用PyPI中的库。在单个测试上应用装饰程序,使其在花费太长时间时终止: import timeout_decorator class TestCaseWithTime
python
frameworkunittest
。是否可以通过框架的能力指定测试超时?如果否,是否可以为所有测试指定一个超时
,并为一些单独的测试为每个测试指定一个私有值?我想为所有测试定义一个
全局超时
(默认情况下他们会使用它),并为一些可能需要很长时间的测试定义一个超时。据我所知,不包含任何对测试超时的支持
您可以尝试使用PyPI中的库。在单个测试上应用装饰程序,使其在花费太长时间时终止:
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()
与
我使用带有keyowrd的
构建了一个unittest
超时解决方案
这种方法还使用信号
,因此它可能只在*nix系统上有效(我只在Ubuntu 16.04环境中运行过它)
导入信号,添加TestTimeout
异常:
在单元测试中嵌入带有测试超时()的
块:
def测试_-foo(自身):
测试超时(5):#测试有5秒时间完成
... foo单元测试代码。。。
使用这种方法,超时的测试将由于raise TestTimeout异常而导致错误
或者,您可以将带有test\u timeout()的块包装在try:except TestTimeout:
块中,并以更大的粒度处理异常(例如跳过测试而不是错误)。。我没有使用unittest.main()
,但我希望我的案例可以采用decorator
。但是我的测试不是在单线程中进行的…@Jury检查中的“多线程”部分-你只需要在多线程环境中使用timeout\u decorator.timeout(timeout,use\u signals=False)
。我不知道发生了什么,但是use\u signals=False
对我不起作用,但在信号方面它看起来很有效。正如我发现的,这个模块使hook to call\u超时。\uuu调用\uuu
而不是直接使用testmethod。问题在于,testmethod的self
丢失(替换)为\u Timeout
的self
。调用时,testmethod
没有任何self
,并且失败。我不知道发生了什么,也不知道如何解决。全局超时的把戏不太管用,但我确实做到了。只能使用带异常的decorator:@timeout\u decorator.timeout(timeout,timeout\u exception=StopIteration)
。你需要在所有潜在的堆叠测试中使用这个装饰器。在我的例子中,它是在与异步相关的测试中/websocket@AdamWildavsky恐怕C++代码中会有太多的事情发生。您可以尝试在一个子进程中运行整个测试套件,由父进程负责超时-这有点像大锤式的方法,但这是我能提供的最好的方法。也许最好把它作为一个单独的问题来看待,因为它应该被视为一个独立的问题。
timeout_decorator.timeout(GLOBAL_TIMEOUT)(unittest.main)()
import signal
...
class TestTimeout(Exception):
pass
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)
def test_foo(self):
with test_timeout(5): # test has 5 seconds to complete
... foo unit test code ...