How to retrieve the markers for py.test in conftest.py?

Question:

I am running tests with py.test and want to access the markers I have set on the command line. I have tried the following code inside conftest.py (based on the documentation I found here) in a fixture that is used by every running test (i.e. a fixture that setup the test):

@pytest.fixture
def basedriver(request):
    ...
    node = request.node
    print("Marker: %s" % str(node.get_marker('set1')))
    ...

but when I invoke the test like follows:

py.test -s -m "set1 or ready"

I get the following output

Marker: None

I seem to do it wrong. How to do it right?

Ideally, I can retrieve the whole string, i.e. “set1 or ready”…

Asked By: Alex

||

Answers:

request.node is the test function object, so request.node.get_closest_marker('set1') returns the marker attached to the test currently being executed, or None if a marker with the name cannot be found. For example, running a test

@pytest.fixture
def basedriver(request):
    node = request.node
    print('Marker:', node.get_closest_marker('set1'))

@pytest.mark.set1
def test_spam(basedriver):
    assert True

def test_eggs(basedriver):
    assert True

will print

test_spam.py::test_spam Marker: MarkInfo(_marks=[Mark(name='set1', args=(), kwargs={})])
PASSED
test_spam.py::test_eggs Marker: None
PASSED

What you want is the passed value of the command line argument -m. Access it via config fixture:

@pytest.fixture
def basedriver(pytestconfig):
    markers_arg = pytestconfig.getoption('-m')
    print('markers passed from command line:', markers_arg)
    ...
Answered By: hoefling

Unfortunately the

`request.node.get_marker('set1') `

is not working anymore.
But you can change it to:

request.node.get_closest_marker('set1') 

see:

https://docs.pytest.org/en/latest/historical-notes.html#update-marker-code

Answered By: looki

Came across this while looking for a way to find markers that a test has been marked with and the previous answers weren’t working for me since get_closest_marker('set1') requires "hard-coding" a value and what I wanted was to be able to grab and log the current marker without knowing what it "should" be.

Below example helped me with my use case.

    import pytest
    from loguru import logger


    @pytest.fixture(autouse=True)
    def get_marker(request):
        markers = request.node.own_markers
        for marker in markers:
            logger.info(f'Marker: {marker.name}')
    
    
    @pytest.mark.tagged
    @pytest.mark.tagged_again
    def test_tag_test():
        logger.info('This is a tagged test')
    
    
    def test_non_tag_test():
        logger.info('This is NOT a tagged test')

Output:

23/Aug/2022 10:8:9 – INFO: Marker: tagged_again
23/Aug/2022 10:8:9 – INFO: Marker: tagged
23/Aug/2022 10:8:9 – INFO: This is a tagged test

Answered By: Eitel Dagnin
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.