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

如何让pytest按上次执行时间排序测试并结合--ff选项?

pytest 按上次执行时间排序测试用例(结合失败用例优先)

现成插件方案

可以直接使用pytest-duration-order插件,它支持基于上次测试的执行时长对用例排序,同时能和pytest原生的--ff(失败用例优先)选项兼容:

  • 安装插件:pip install pytest-duration-order
  • 使用方式:运行测试时加上--duration-order参数,同时配合--ff即可实现「先跑失败用例,剩余用例按上次执行时间排序」的需求。默认是长耗时用例优先,如果需要短耗时优先,可加上--duration-order-reverse参数。

手动编写插件实现

如果需要自定义逻辑,可通过pytest的钩子函数结合内置缓存机制实现,步骤如下:

1. 记录测试用例的执行时长

在项目根目录的conftest.py中添加钩子函数,将每个测试的执行时长存入pytest缓存:

def pytest_runtest_makereport(item, call):
    if call.when == "call":
        # 从缓存中读取已有的时长记录,没有则初始化空字典
        cache = item.config.cache
        test_durations = cache.get("test_durations", {})
        # 存入当前测试的执行时长
        test_durations[item.nodeid] = call.duration
        cache.set("test_durations", test_durations)

2. 自定义测试用例排序逻辑

同样在conftest.py中添加pytest_collection_modifyitems钩子,实现「失败用例优先,剩余用例按上次时长排序」的逻辑:

def pytest_collection_modifyitems(config, items):
    cache = config.cache
    # 获取上次测试的失败用例列表(pytest原生--ff依赖的缓存键)
    last_failed = cache.get("cache/lastfailed", {})
    # 获取之前记录的测试时长
    test_durations = cache.get("test_durations", {})

    # 拆分失败用例和普通用例
    failed_items = []
    normal_items = []
    for item in items:
        if item.nodeid in last_failed:
            failed_items.append(item)
        else:
            normal_items.append(item)
    
    # 对普通用例按上次执行时长排序(这里设为长耗时优先,reverse=False则为短耗时优先)
    normal_items.sort(key=lambda x: test_durations.get(x.nodeid, 0), reverse=True)
    
    # 重新组合用例列表:失败用例在前,排序后的普通用例在后
    items[:] = failed_items + normal_items

3. 使用方式

直接运行测试时加上--ff参数即可,无需额外参数:

pytest --ff

第一次运行时无缓存数据,排序不生效;从第二次运行开始,就会按照预期逻辑执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:01:12