Naggappan Ramukannan
Naggappan Ramukannan

Reputation: 2812

How to check which pytest mark is the test running for

I have a test file eg: test_my_api.py

And I call the pytest to start executing using below command, to run test only with specific mark

pipenv run pytest -m "integration"

Now in my test_my_api.py file I have multiple functions marked as "integration"

Also I have a global variable configured as below, and using this global value DATA in all methods

DATA = get_my_data()

Now I have another mark called "smoke", now some test cases has both the mark "smoke" and "integration". For smoke i need global data as different as below,

DATA = get_smoke_data()

The issue is while running the test case I can't split for which mark this test case is getting called . i.e for smoke or for integration. How can I get this info in global level ?

Previously I know there was something called Mark info eg: from _pytest.mark import MarkInfo but this is removed now. And this is available only inside every method How can I get it on global level

Upvotes: 8

Views: 4545

Answers (2)

tgoodhart
tgoodhart

Reputation: 3266

If you want to be able to support marker expressions, such as -m foo OR bar or dynamically added markers (i.e. add_marker()), then you may need something more elaborate:

@pytest.fixture(scope="function")
def active_marks(request):

  # Collect all the marks for this node (test)
  current_node = request.node
  marks = []
  while current_node:
    marks += [mark.name for mark in current_node.iter_markers()]
    current_node = current_node.parent

  # Get the mark expression - what was passed to -m
  markExpr = request.config.option.markexpr

  # Compile the mark expression
  from _pytest.mark.expression import Expression
  compiledMarkExpr = Expression.compile(markExpr)

  # Return a sequence of markers that match
  return [ mark for mark in marks if compiledMarkExpr.evaluate( lambda candidate: candidate == mark ) ]


class TestClass:
  def test_foo(active_marks):
    print(f"Active marks are {active_marks}")

Upvotes: 2

Shakeel
Shakeel

Reputation: 2015

If I have understood correctly you trying to know which marker is called for test method having more than one marker during run time ?

Is this something you are looking for ?

import pytest

@pytest.fixture
def my_common_fixture(request, pytestconfig):
    markers_arg = pytestconfig.getoption('-m')
    request.cls.marker_name = markers_arg


class TestSmokeIntegration:
    @pytest.mark.smoke
    @pytest.mark.integration
    def test_for_smoke_integration(self, my_common_fixture):
        print("marker used: ", self.marker_name)
        assert True

    def test_somthing_else(my_common_fixture):
        assert True
pytest -vvv -s test_marker.py -m smoke

output:

test_marker.py::TestSmokeIntegration::test_for_smoke_integration markers used:  smoke
PASSED
pytest -vvv -s test_marker.py -m integration

output:

test_marker.py::TestSmokeIntegration::test_for_smoke_integration marker used:  integration
PASSED

Upvotes: 11

Related Questions