Search code examples
pythonpytestfixtures

Pytest: create incremental fixture value with argument


Okay so I have this fixture:

@pytest.fixture
def dummy_name():
    def func(name="Dummy Name"):
        num = 2
        while True:
            yield name
            if num > 2:
                tags = name.rsplit("_", 1)
                name = f"{tags[0]}_{num}"
            else:
                name += f"_{num}"
            num += 1

    return func

@pytest.fixture
def dummy_admin_name(dummy_name):
    return dummy_name(name="Dummy Admin")

I can use it like this:

def some_function(dummy_admin_name):
     print(next(dummy_admin_name))
     print(next(dummy_admin_name))
     print(next(dummy_admin_name))

Which returns:

Dummy Admin
Dummy Admin_2
Dummy Admin_3

But the problem is I have to create that secondary fixture all the time for different strings, because calling the the base dummy_name fixture doesn't work:

def some_function(dummy_name):
     print(next(dummy_name(name="Dummy Admin")))
     print(next(dummy_name(name="Dummy Admin")))
     print(next(dummy_name(name="Dummy Admin")))

Which returns:

Dummy Admin
Dummy Admin
Dummy Admin

Clearly because adding the argument three times resets the name value every time.

How could I make that input persistent for future calls without a new fixture?


Solution

  • As you wrote, you cannot call the fixture multiple times, as it will re-create the function each time. However, you could just create the callable before using it:

    def test_something(dummy_name):
        dummy_admin = dummy_name(name="Dummy Admin")
        print(next(dummy_admin))
        print(next(dummy_admin))
        print(next(dummy_admin))
        dummy_user = dummy_name(name="Dummy User")
        print(next(dummy_user))
        print(next(dummy_user))
    

    which prints:

    Dummy Admin
    Dummy Admin_2
    Dummy Admin_3
    Dummy User
    Dummy User_2