根据执行时间通过测试

CIs*_*ies 3 python pytest

是否pytest有像一个计时器测试?

IE

@pytest.mark.timer(60)
def test_this_code_runs_in_less_than_x():
    bla()
Run Code Online (Sandbox Code Playgroud)

如果bla执行超过 60 秒,哪个会失败?

我可以使用自己的装饰器轻松实现这一点,例如:

import time, threading                                                                                                                                                                                                     
def timeout(func):                                                                                                                                                                                              
    def wrapper():                                                                                                                                                                                              
        start_time = time.time()                                                                                                                                                                                
        timeout = start_time + 1                                                                                                                                                                                
                                                                                                                                                                                                                
        th = threading.Thread(target=func)                                                                                                                                                                      
        th.start()                                                                                                                                                                                              
        while time.time() < timeout and th.isAlive():                                                                                                                                                           
            pass                                                                                                                                                                                                
        if th.isAlive():                                                                                                                                                                                        
            raise TimeoutError()                                                                                                                                                                                
        th.join()                                                                                                                                                                                               
                                                                                                                                                                                                                
    return wrapper                                                                                                                                                                                              
                                                                                                                                                                                                                
                                                                                                                                                                                                                
@timeout                                                                                                                                                                                                        
def _test():                                                                                                                                                                                                    
    time.sleep(2)                                                                                                                                                                                               
                                                                                                                                                                                                                
                                                                                                                                                                                                                
def test_should_fail_after_one_second():                                                                                                                                                                        
    _test() 
Run Code Online (Sandbox Code Playgroud)

但我不想发明轮子...

我知道 pytest 可以有一个 --timeout 参数,但我正在寻找一些东西作为测试定义的一部分,而不是影响所有测试的可配置参数

DV8*_*2XL 5

使用pytest-timeout插件,您可以用超时时间标记单个测试,以秒为单位:

@pytest.mark.timeout(60)
def test_foo():
    pass
Run Code Online (Sandbox Code Playgroud)

您可以通过向method装饰器添加参数来明确选择以下两种“线程方法” :

  • thread: 在单独的线程中运行睡眠,并在达到超时时终止测试进程。请注意,这可能会导致正常 JUnit XML 输出或夹具拆卸出现问题。
  • signal:安排 SIGALRM 警报,在达到超时时取消测试。这允许您的测试运行正常完成。但是,如果您的代码已经使用 SIGALRM,这可能会干扰其正常功能。

如果您的系统支持signal.SIGALRM(通常是Unix),则signal默认使用线程方法。否则,thread将改用该方法。