Python 【求助】如何捕获 pytest parametrize 中的 timeout 异常

绪文 · 2024年08月03日 · 最后由 绪文 回复于 2024年08月06日 · 4334 次阅读

目前使用的接口测试方案,是从数据库中读取用例,使用 pytest 的 parametrize 轮询执行。希望使用 pytest-timeout 将超时的错误抛出然后触发告警。现在碰到问题是下图中的 Timeout 错误无法捕获,请大佬们支支招。

import time
import pytest

@ pytest.mark.timeout(2)
@ pytest.mark.parametrize("s", [1, 3, 1])
def test_timeout(s):
    # 模拟超时接口用例
    time.sleep(s)
    print(f"demo-{s}")

共收到 4 条回复 时间 点赞

把 parametrize 装饰器放 timeout 上面

接楼上,应该顺序反了

Zion 回复

感谢你的回复,我尝试修改代码,将 parametrize 放在 timeout 上面,仍无法捕获到 Timeout 异常

@ pytest.mark.parametrize("s", [1, 3, 1])
@ pytest.mark.timeout(2)
def test_timeout(s):
    try:
        do_test(s)
    except Exception as e:
        print(e)
        pytest.fail('Test timeout!')


def do_test(t):
    time.sleep(t)
    assert True

ChatGPT 给出了个方案,我整合起来代码如下。这样的确可以捕获到 Timeout 异常,只是结合到业务场景中略显复杂,如果有简洁的方案就更好了

import time
import pytest
from concurrent.futures import ThreadPoolExecutor, TimeoutError as FuturesTimeoutError


@ pytest.mark.parametrize("s", [1, 3, 1])
def test_timeout(s):
    def do_test(t):
        time.sleep(t)
        assert True

    timeout_limit = 2

    result = run_with_timeout(do_test, timeout_limit, s)
    if result == "Timeout occurred":
        pytest.fail("Test time out")


def run_with_timeout(func, timeout, *args, **kwargs):
    with ThreadPoolExecutor(max_workers=1) as executor:
        try:
            future = executor.submit(func, *args, **kwargs)
            return future.result(timeout=timeout)
        except FuturesTimeoutError:
            return "Timeout occurred"

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册