Search code examples
pythonpytestfixtures

How to retrive decorated test function name and arguments in a pytest fixture


I want to run the decorated test manually in its fixture, can I do that? for example:

@pytest.fixture
def my_fixture(request):
    call test_my_function
    call test_my_fucntion again

def test_my_function(my_fixture):
    pass

The user-case is as below: We want to make a test framework, in which we have setup and teardown phase, and a special target: we want to run the test twice times between setup and teardown. That's because we have a common refreash function, it will reconstruct the database of the test, we want to confirm everything are unchanged after refresh. So there should be two times test before and after the refresh function call.

I want to know how to get function name and arguments, and run it manually


Solution

  • We can use getfullargspec (from import inspect):

    import inspect
    argspec = inspect.getfullargspec(test_my_function)
    print(argspec.args)
    

    Outputs:

    ['my_fixture']
    

    or just:

    print(test_my_function.__code__.co_varnames)
    

    Outputs:

    ('my_fixture',)
    

    To get the __name__s of the functions:

    print(my_fixture.__name__)
    print(test_my_function.__name__)
    

    Outputs:

    my_fixture
    test_my_function
    

    If you want to get the args and __name__ of the pytest decorated function my_fixture we can use @pytest.mark.parametrize:

    @pytest.mark.parametrize
    def my_fixture(request):
        pass
    
    def test_my_function(my_fixture):
        pass
    
    test_my_function(my_fixture)
    print(my_fixture.__code__.co_varnames)
    print(my_fixture.__name__)
    

    Outputs:

    ('request',)
    my_fixture
    

    To continue using the pytest.fixture decorator we can add a parametrize attribute pytest.mark.parametrize to it:

    pytest.fixture.parametrize = pytest.mark.parametrize
    
    @pytest.fixture.parametrize
    def my_fixture(request):
        pass
    
    def test_my_function(my_fixture):
        pass
    
    test_my_function(my_fixture)
    print(my_fixture.__code__.co_varnames)
    print(my_fixture.__name__)
    

    Outputs:

    ('request',)
    my_fixture