Pytest 在最后一次迭代后参数化 运行

Pytest parametrize run after the last iteration

当使用 @pytest.mark.parametrize('arg', param) 时,有没有办法查明 param 中的最后一项是否是 运行?我问的原因是我想要 运行 一个该测试独有的清理函数,它应该只在 param.

的最后一次迭代之后 运行
param = [(1, 'James'), (2, 'John')]
@pytest.mark.parametrize('id, user', param)
def test_myfunc(id, user):
    # Do something
    print(user)

    # Run this only after the last param which would be after (2, 'John')
    print('All done!')

我可以 运行 一个检查 param 值的条件,但我只是想知道 pytest 是否有办法做到这一点。

您需要在 pytest 挂钩中执行此逻辑,特别是 pytest_runtest_teardown 挂钩。

假设您的测试如下所示,

import pytest

param = [(1, 'James'), (2, 'John')]
@pytest.mark.parametrize('id, user', param)
def test_myfunc(id, user):
    print(f"Iteration number {id}")

在测试文件夹的根目录中,创建一个 conftest.py 文件并放置以下内容,

func_of_interest = "test_myfunc"

def pytest_runtest_teardown(item, nextitem):
    curr_name = item.function.__qualname__
    # check to see it is the function we want
    if curr_name == func_of_interest:
        # check to see if there are any more functions after this one
        if nextitem is not None:
            next_name = nextitem.function.__qualname__
        else:
            next_name = "random_name"
        # check to see if the next item is a different function
        if curr_name != next_name:
            print("\nPerform some teardown once")

然后当我们运行它时,它会产生如下输出,

===================================== test session starts ======================================
platform darwin -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
cachedir: .pytest_cache
rootdir: ***
collected 2 items                                                                              

test_grab.py::test_myfunc[1-James] Iteration number 1
PASSED
test_grab.py::test_myfunc[2-John] Iteration number 2
PASSED
Perform some teardown once

正如我们所见,在测试调用的最后一次迭代之后,拆解逻辑只被调用了一次。