Search code examples
pytestparameterized

pytest parameterized method setup


I have a parameterized pytest test method, test_1. Before all the parameterized cases are run for this test method, I'd like to call another method, tmp_db_uri, which creates a temporary database and yields the uri for the database. I only want to call that generator once, so that I can use the same temporary database for all the test cases. I thought that if I called it from a fixture (db_uri), that would do the trick, since I thought that fixtures are created once per test, but it seems that the fixture is getting called for each case in this test, and a new temporary database is being created each time.

What is the correct way to do this? Is there a way to run a setup for this method before all the cases are run, to use just one tmp_db_uri? I don't want the temporary database hanging around for the entire test module - just for the duration of this one test (cleanup is handled by a context manager on tmp_db_uri).

I currently have something that looks similar to this:

@pytest.fixture
def db_uri(tmp_db_uri):
    return tmp_db_uri

@pytest.mark.parameterize(("item1","item2"), ((1, "a"), (2, "b")))
def test_1(item1, item2, db_uri):
    print("do something")

Solution

  • You can create a module level fixture ,so that it's created only once for the entire test module or you can create a global variable and return the db if it is already created or create otherwise.

    @pytest.fixture(scope="module")
    def db_uri(tmp_db_uri):
        return tmp_db_uri
    

    or

    TMP_DB = None
    @pytest.fixture
    def db_uri(tmp_db_uri):
        global TMP_DB
        if not TMP_DB:
            # do your stuff to create tmp_db 
            TMP_DB = tmp_db_uri
        return TMP_DB