Search code examples
pytestfixtures

pytest: how to get return value from a fixture and pytest.mark.parametrize in the same function


I am trying to accomplish the following:

  • pytest fixture returns the db handle

  • pytest.mark.parametrize passes the arguments against which the test will be run

I went through pytest docs, multiple forums. I did not get any answer. Can someone suggest a solution for the problem? or an alternate way of doing this?

EDIT 1: I want the db connections to happen only once in setup function. This db connection is used in all test function. Test function will be run against parameters from the parametrize values. How do I return the db_conn value from fixture?

import pytest

@pytest.fixture(scope="module")
def conn():
    db_conn = get_db_conn()
    yield db_conn
    db_conn.close()


@pytest.mark.parametrize("arg",[1,2,3])
def test_1(arg):
    db_conn.insert(arg)
    process(arg)

@pytest.mark.parametrize("arg",["a","b","c"])
def test_2(arg):
    db_conn.insert(arg)
    process(arg)


Solution

  • Have tried passing conn fixture as an argument for tests?

    import pytest
    
    @pytest.fixture(scope="module")
    def conn():
        db_conn = get_db_conn()
        yield db_conn
        db_conn.close()
    
    
    @pytest.mark.parametrize("arg",[1,2,3])
    def test_1(arg, conn):
        conn.insert(arg)
        process(arg)
    
    @pytest.mark.parametrize("arg",["a","b","c"])
    def test_2(arg, conn):
        conn.insert(arg)
        process(arg)
    

    This simple mock (test_fixture_params.py) should demonstrate the usage:

    import pytest
    
    
    @pytest.fixture(scope="module")
    def conn():
        print('Opening db connection')
        yield 'MY DB CONNECTION'
        print('Closing db connection')
    
    
    @pytest.mark.parametrize("arg",[1,2,3])
    def test_1(arg, conn):
        print(conn, arg)
    
    
    @pytest.mark.parametrize("arg",["a","b","c"])
    def test_2(arg, conn):
        print(conn, arg)
    

    For pytest -s test_fixture_params.py the output should be:

    $ pytest -s test_fixture_params.py 
    ===================================================== test session starts =====================================================
    platform linux -- Python 3.8.1, pytest-5.4.3, py-1.8.1, pluggy-0.13.1
    collected 6 items                                                                                                             
    
    test_fixture_params.py Opening db connection
    MY DB CONNECTION 1
    .MY DB CONNECTION 2
    .MY DB CONNECTION 3
    .MY DB CONNECTION a
    .MY DB CONNECTION b
    .MY DB CONNECTION c
    .Closing db connection
    
    
    ====================================================== 6 passed in 0.03s ======================================================
    

    I hope this helps!