0

When using @pytest.mark.parametrize('arg', param) is there a way to find out if the last item in param is being run? The reason I'm asking is I want to run a cleanup function unique to that test that should only run after the very last iteration of 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!')

I can run a conditional which checks for the value of param but I was just wondering if pytest has a way for this.

enchance
  • 29,075
  • 35
  • 87
  • 127
  • Can't you clean after each test ? That's a cleaner way to do it – azro Apr 09 '21 at 08:21
  • For this test I can't since each test builds on the previous one. The test writes to Redis so the data is stored for the next test to use. – enchance Apr 09 '21 at 08:26
  • You have a specific class to run them : a setup method to write data, then tests on them, them a cleanup method – azro Apr 09 '21 at 08:27

1 Answers1

1

You'll need to perform this logic within a pytest hook, specifically the pytest_runtest_teardown hook.

Assuming your test looks like the following,

import pytest

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

In the root of your test folder, create a conftest.py file and place the following,

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")

Then when we run it, it produces the following output,

===================================== 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

As we can see, the teardown logic was called exactly once, after the final iteration of the test call.

gold_cy
  • 13,648
  • 3
  • 23
  • 45