pytest 5.x+ upgrade and use a command line flag to run/skip decorated tests

36 views Asked by At

I'm trying to upgrade from pytest 4.x to something newer. However, I'm running into issues where pytest.config was removed and I'm not sure how to accommodate the new syntax. Specifically, I'm trying to specify a command line flag that can run or skip specific decorated tests depending on whether or not the flag is present.

This is how it works in pytest 4.x.

# common.py
integration = pytest.mark.skipif(
    not pytest.config.getoption('--integration', False),
)

Then, elsewhere in the tests..

# test_something.py 
from .common import integration 

@integration
def test_mytest():
    1 == 1

@integration
def test_other_mytest():
    2 == 2

In newer versions of pytest, the above fails with:

AttributeError: module 'pytest' has no attribute 'config'

In pytest 5.x+, how can I achieve the same result as above - how can I pass in flag to pytest and run/skip certain tests based on that flag? Preferably, it would be nice to decorate them as in the example, as I have a lot of tests using the decorator syntax and it could be difficult to update them all. Any advice is much appreciated.

1

There are 1 answers

1
larsks On BEST ANSWER

One option is to use a custom marker and the existing -m command line option. If you redefine your integration decorator like this:

import pytest

integration = pytest.mark.integration

@integration
def test1():
    pass

def test2():
    pass

And define the integration marker in pytest.ini:

[pytest]
markers =
  integration

Then you can run all tests:

$ pytest -v
========================================= test session starts =========================================
platform linux -- Python 3.11.6, pytest-7.2.2, pluggy-1.0.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/lars/tmp/python, configfile: pytest.ini
collected 2 items

test_skip.py::test1 PASSED                                                                      [ 50%]
test_skip.py::test2 PASSED                                                                      [100%]

========================================== 2 passed in 0.00s ==========================================

Or only integration tests:

$ pytest -v -m integration
========================================= test session starts =========================================
platform linux -- Python 3.11.6, pytest-7.2.2, pluggy-1.0.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/lars/tmp/python, configfile: pytest.ini
collected 2 items / 1 deselected / 1 selected

test_skip.py::test1 PASSED                                                                      [100%]

=================================== 1 passed, 1 deselected in 0.00s ===================================

Or only non-integration tests:

$ pytest -v -m 'not integration'
========================================= test session starts =========================================
platform linux -- Python 3.11.6, pytest-7.2.2, pluggy-1.0.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/lars/tmp/python, configfile: pytest.ini
collected 2 items / 1 deselected / 1 selected

test_skip.py::test2 PASSED                                                                      [100%]

=================================== 1 passed, 1 deselected in 0.00s ===================================

This meets your goal of not having to update all your tests.