Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collect py.test tests info with markers

Tags:

pytest

I'm using py.test and I want to get the list of tests that I have with marker info included. When I use the --collect-only flag I get the test functions. Is there a way to get the assigned markers for each test also?


Based on Frank T's answer I created a workaround code sample:

from _pytest.mark import MarkInfo, MarkDecorator
import json


def pytest_addoption(parser):
    parser.addoption(
        '--collect-only-with-markers',
        action='store_true',
        help='Collect the tests with marker information without executing them'
    )


def pytest_collection_modifyitems(session, config, items):
    if config.getoption('--collect-only-with-markers'):
        for item in items:
            data = {}

            # Collect some general information
            if item.cls:
                data['class'] = item.cls.__name__
            data['name'] = item.name
            if item.originalname:
                data['originalname'] = item.originalname
            data['file'] = item.location[0]

            # Get the marker information
            for key, value in item.keywords.items():
                if isinstance(value, (MarkDecorator, MarkInfo)):
                    if 'marks' not in data:
                        data['marks'] = []

                    data['marks'].append(key)

            print(json.dumps(data))

        # Remove all items (we don't want to execute the tests)
        items.clear()
like image 561
László Ács Avatar asked Oct 12 '16 06:10

László Ács


2 Answers

I don't think pytest has built-in behavior to list test functions along with the marker information for those tests. A --markers command lists all registered markers, but that's not what you want. I briefly looked over the list of pytest plugins and didn't see anything that looked relevant.

You can write your own pytest plugin to list tests along with marker info. Here is documentation on writing a pytest plugin.

I would try using the "pytest_collection_modifyitems" hook. It is passed a list of all tests that are collected, and it doesn't need to modify them. (Here is a list of all hooks.)

The tests passed in to that hook have a get_marker() method if you know the name of the marker you're looking for (see this code for example). When I was looking through that code, I could not find an official API for listing all markers. I found this to get the job done: test.keywords.__dict__['_markers'] (see here and here).

like image 172
Frank T Avatar answered Nov 05 '22 04:11

Frank T


You can find markers by a name attribute in the request.function.pytestmark object

@pytest.mark.scenarious1
@pytest.mark.scenarious2
@pytest.mark.scenarious3
def test_sample():
    pass

@pytest.fixture(scope='function',autouse=True)
def get_markers():
    print([marker.name for marker in request.function.pytestmark])

>>> ['scenarious3', 'scenarious2', 'scenarious1']

Note, that they were listed in the reversed order by default.

like image 1
klapshin Avatar answered Nov 05 '22 05:11

klapshin