Search code examples
pytest

How can I conditionally skip a parameterized pytest scenario?


I need to flag certain tests to be skipped. However, some of the tests are parameterized and I need to be able to skip only certain of the scenarios.

I invoke the test using py.test -m "hermes_only" or py.test -m "not hermes_only" as appropriate.

Simple testcases are marked using:

@pytest.mark.hermes_only
def test_blah_with_hermes(self):

However, I have some parameterized tests:

outfile_scenarios = [('buildHermes'),
                     ('buildTrinity')]

@pytest.mark.parametrize('prefix', outfile_scenarios)
def test_blah_build(self, prefix):
    self._activator(prefix=prefix)

I would like a mechanism to filter the scenario list or otherwise skip certain tests if a pytest mark is defined.

More generally, how can I test for the definition of a pytest mark?


Solution

  • [Updated answer: With newer versions of python, it is now necessary to use the pattern described by @Migwell]

    The documentation cited by @Migwell uses skipif but if you want to use a custom mark defined elsewhere, here is an updated version of my previous example:

    import pytest
    
    scenarios = [pytest.param('trinity', 'buildTrinity',
                              marks=pytest.mark.trinity_only),
                 pytest.param('legacy',  'buildLegacy',
                              marks=pytest.mark.legacy_only)]
    
    @pytest.mark.parametrize('tcid, prefix', scenarios,
                             ids=[id[0] for id in scenarios])
    def test_sample(self, tcid, prefix):
        pass        
    

    Additionally, custom marks should be registered to avoid PytestUnknownMarkWarning complaints. In conftest.py, add the following:

    def pytest_configure(config):
        config.addinivalue_line("markers", "trinity_only: Runs trinity_only tests.")
        config.addinivalue_line("markers", "legacy_only: Runs legacy_only tests.")
    

    Alternatively, they can be registered in pytest.ini:

    [pytest]
    markers =
        trinity_only: Runs trinity_only tests.
        legacy_only: Runs legacy_only tests.
    

    Custom marks are used by using pytest's -m option. For example, pytest -m trinity_only

    I hope this addresses your problem with my original answer @adam-hoelscher