如何通过pytest定位耗时最长的n个测试用例创建过程?
找出pytest中耗时最长的测试用例创建过程
默认的--durations参数只能统计测试执行阶段的耗时,没法覆盖参数化中测试用例参数的生成过程(也就是你代码里create_test_params这类函数的执行时间)。下面是几种可行的手动统计方案:
方法1:给参数生成函数加计时装饰器
写一个简单的装饰器,用来记录每个参数生成函数的调用耗时,最后在测试结束时输出耗时最长的n个记录。
示例代码:
import time from collections import defaultdict # 存储每个函数的调用耗时记录 param_gen_times = defaultdict(list) def track_param_gen_time(func): def wrapper(*args, **kwargs): start = time.perf_counter() result = func(*args, **kwargs) elapsed = time.perf_counter() - start # 记录函数名、参数和耗时 param_gen_times[func.__name__].append({ "args": args, "kwargs": kwargs, "elapsed": elapsed }) return result return wrapper # 用装饰器包裹你的参数生成函数 @track_param_gen_time def create_test_params(n): # 原函数逻辑 time.sleep(0.1) # 模拟耗时操作 return {"n": n} @track_param_gen_time def create_test_params_alt(n): # 原函数逻辑 time.sleep(0.5) # 模拟耗时操作 return {"n": n} # 在pytest结束时输出统计结果 def pytest_sessionfinish(session, exitstatus): print("\n=== 耗时最长的参数生成记录 ===") # 把所有记录合并成一个列表 all_records = [] for func_name, records in param_gen_times.items(): for record in records: all_records.append({ "func": func_name, "args": record["args"], "elapsed": record["elapsed"] }) # 按耗时排序,取前10个 top_n = 10 for idx, record in enumerate(sorted(all_records, key=lambda x: x["elapsed"], reverse=True)[:top_n], 1): print(f"{idx}. {record['func']}{record['args']}: {record['elapsed']:.4f}s")
把这段代码放到你的conftest.py或者测试模块中,运行测试后,会在终端输出耗时最长的前10个参数生成调用记录。
方法2:在测试用例收集阶段统计总耗时
如果你的参数生成逻辑是直接写在@pytest.mark.parametrize的参数列表里(而非单独函数),可以利用pytest_generate_tests钩子统计整个参数列表的生成总耗时:
import time def pytest_generate_tests(metafunc): # 检查当前测试函数是否有parametrize标记 for param in metafunc.definition.iter_markers(name="parametrize"): argnames, argvalues = param.args[:2] # 记录参数生成的开始时间 start = time.perf_counter() # 重新执行参数生成逻辑(注意:若原逻辑有副作用,需调整实现) _ = list(argvalues) elapsed = time.perf_counter() - start print(f"测试函数{metafunc.function.__name__}的参数生成总耗时:{elapsed:.4f}s")
这种方式适合快速定位哪组参数化的生成过程整体耗时久,若需单个参数的耗时,优先用方法1。
注意事项
- 如果参数生成函数有缓存逻辑,统计时要排除缓存命中的情况,避免结果失真。
- 统计短耗时推荐用
time.perf_counter(),它的精度比time.time()更高。
内容的提问来源于stack exchange,提问作者Nico Schlömer
相关产品推荐
相关产品推荐

