使用 pytest 对参数化基准进行分组

问题描述 投票:0回答:2

我目前正在使用 pytest-benchmark 对我针对非重新平衡二叉搜索树制作的 AVL 树的实现进行基准测试。到目前为止,它似乎对我来说运作良好,但我遇到了一个问题。为了巩固测试文件,我发现我可以参数化测试,还可以对基准测试的输出进行分组以提高可读性,但我似乎无法同时执行这两个操作。

我当前的插入基准:

# always the same for repeatability
random.seed(0x1C2C6D66)

def insertRandomOrder(t, n):
  tree = t()
  for i in range(0,n):
    tree.insert(random.randint(0,0x7FFFFFFF),i)

def insertDescendingOrder(t, n):
  tree = t()
  for i in range(0,n):
    tree.insert(n-i,i)

def insertOutInOrder(t, n):
  tree = t()
  for i in range(0,n):
    idx = (i%2)*n + (1-2*(i%2))*i
    tree.insert(idx,i)

def insertAscendingOrder(t, n):
  tree = t()
  for i in range(0,n):
    tree.insert(i,i)

types = [BaseTree, AvlTree]
sizes = [100,300,1000]
cases = [insertAscendingOrder, insertDescendingOrder, insertOutInOrder, insertRandomOrder]

@pytest.mark.parametrize('t', types)
@pytest.mark.parametrize('n', sizes)
@pytest.mark.parametrize('case', cases)
def test_insert_benchmark(benchmark, t, n, case):
  benchmark(case, t, n)

这是输出:

有谁知道我可以对输出进行分组的方法,但是我的示例中的

case
?或者更好的是,通过
(case,n)
元组?

python pytest
2个回答
1
投票

一个有用的评论说 pytest 的主分支正在支持这个确切的功能,但我无法让它工作(祈祷下一个版本)。

与此同时,我想出了这个方便的解决办法。我可以使用此方法按

case
进行分组,但不能按
(case,n)
进行分组。我在每个测试用例上方添加了一个
@benchmark_this
装饰器来包装
benchmark
调用。即使没有按测试用例分组的额外好处,它也非常方便!

def benchmark_this(test):
  def wrapper(benchmark, t, n):
    benchmark(test, None, t, n)
  return wrapper

types = [BaseTree, AvlTree]
sizes = [100,300,1000]

@pytest.mark.parametrize('t', types)
@pytest.mark.parametrize('n', sizes)
@benchmark_this
def test_insertRandomOrder(benchmark, t, n):
  random.seed(0x1C2C6D66)
  tree = t()
  for i in range(n):
    tree.insert(random.randint(0, 0x7FFFFFFF), i)

@pytest.mark.parametrize('t', types)
@pytest.mark.parametrize('n', sizes)
@benchmark_this
def test_insertDescendingOrder(benchmark, t, n):
  tree = t()
  for i in range(n):
    tree.insert(n-i, i)

# ...

通过

调用

py.test --benchmark-group-by=func


0
投票

显然,(它没有在任何地方记录,但根据代码和我的测试)我们可以通过使用以编程方式分配组

@pytest.mark.parametrize("param", [1, 2, 3])
@pytest.mark.benchmark(group="Some prefix:")
def test_some_name(param, benchmark):
    benchmark.group += f"{param = }"
    ... rest of code ...

截至 2024 年(4.0 版本),这种情况至少已经持续了 9 年(自 2015 年,3.0 版本以来)

© www.soinside.com 2019 - 2024. All rights reserved.