You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pytest测试threaded_execute函数的TimeoutError与日志记录

测试TimeoutError触发时的日志记录方法

问题背景

我在Python项目中使用pytest测试工具模块,需要验证threaded_execute函数在触发concurrent.futures.TimeoutError时的警告日志记录功能,要求不能安装额外第三方包。函数代码如下:

import logging
from concurrent import futures

logger = logging.getLogger(__name__)

THREAD_TIMEOUT: float = 60  # 为简化直接硬编码值

def threaded_execute(func, *args, timeout=None, **kwargs):
    timeout = timeout or THREAD_TIMEOUT
    while True:
        with futures.ThreadPoolExecutor(max_workers=1) as executor:
            future = executor.submit(func, *args, **kwargs)
            try:
                return future.result(timeout=timeout)
            except futures.TimeoutError as exc:
                logger.warning(exc)
                continue

解决方法

直接用pytest自带的caplog fixture就能搞定,步骤如下:

  • 写一个可控的慢函数:给函数加调用计数器,第一次调用时sleep超过测试超时时间触发错误,第二次正常返回,避免原函数无限循环。
  • 用caplog抓日志:设置日志级别后,就能捕获并验证警告日志。
  • 用短超时参数:测试时传入极小的timeout,不用改原代码的常量,测试更快。

测试代码示例:

import time
from concurrent import futures
import pytest
from your_module import threaded_execute  # 替换成你的实际模块名

def test_threaded_execute_timeout_log(caplog):
    call_count = 0

    def slow_func():
        nonlocal call_count
        call_count += 1
        if call_count == 1:
            # 第一次调用sleep,超过0.1秒的超时设置
            time.sleep(0.2)
        return "success"

    # 设置caplog只捕获WARNING及以上级别的日志
    caplog.set_level(logging.WARNING)
    # 传入0.1秒超时,触发TimeoutError
    result = threaded_execute(slow_func, timeout=0.1)
    
    # 验证最终返回结果正确
    assert result == "success"
    # 验证函数被调用了两次(一次超时重试,一次成功)
    assert call_count == 2
    # 验证警告日志已生成
    assert len(caplog.records) == 1
    assert isinstance(caplog.records[0].msg, futures.TimeoutError)
    assert caplog.records[0].levelname == "WARNING"

说明

  • caplog是pytest内置的fixture,完全不需要额外安装包,能轻松捕获日志内容并做断言。
  • 用计数器控制慢函数的行为,既触发了超时重试,又不会让测试陷入无限循环。
  • 手动传入短超时参数,避免等待原代码中60秒的默认超时,大幅提升测试速度。

内容的提问来源于stack exchange,提问作者serghei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:12:48