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()
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With