28

I have a long run test, which lasts 2 days, which I don't want to include in a usual test run. I also don't want to type command line parameters, that would deselect it and other tests at every usual test run. I would prefer to select a default-deselected test, when I actually need it. I tried renaming the test from test_longrun to longrun and use the command

py.test mytests.py::longrun

but that does not work.

Andy K
  • 4,944
  • 10
  • 53
  • 82
Roland Puntaier
  • 3,250
  • 30
  • 35
  • http://stackoverflow.com/questions/31507713/skipping-pytest-unless-a-parameter-is-present turned out to be the opposite to my question. – Roland Puntaier Oct 12 '15 at 14:56
  • The [official documentation](https://docs.pytest.org/en/latest/example/simple.html#control-skipping-of-tests-according-to-command-line-option) explains how to skip tests according to a command-line option. – Claudio Aug 30 '19 at 11:40
  • See also these (as yet unmarked) duplicates: https://stackoverflow.com/questions/47559524/pytest-how-to-skip-tests-unless-you-declare-an-option-flag, https://stackoverflow.com/questions/52246154/python-using-pytest-to-skip-test-unless-specified – Claudio Aug 30 '19 at 11:43

3 Answers3

26

Alternatively to the pytest_configure solution above I had found pytest.mark.skipif.

You need to put pytest_addoption() into conftest.py

def pytest_addoption(parser):
    parser.addoption('--longrun', action='store_true', dest="longrun",
                 default=False, help="enable longrundecorated tests")

And you use skipif in the test file.

import pytest

longrun = pytest.mark.skipif("not config.getoption('longrun')")

def test_usual(request):
    assert False, 'usual test failed'

@longrun
def test_longrun(request):
    assert False, 'longrun failed'

In the command line

py.test

will not execute test_longrun(), but

py.test --longrun

will also execute test_longrun().

Roland Puntaier
  • 3,250
  • 30
  • 35
  • 2
    This permutation of [sax](https://stackoverflow.com/users/4300672/sax)'s [already useful solution](https://stackoverflow.com/a/33181491/2809027) is even *more* useful. A standard `skipif`-based test decorator always beats a non-standard global `pytest_configure()` hack. For completeness, would you mind editing sax's full `pytest_addoption()` implementation into this solution? – Cecil Curry Oct 21 '17 at 02:23
  • 1
    **Also:** assuming you "borrow" sax's full `pytest_addoption()` implementation as is, there's no need to call `config.getoption()` to obtain this option's value. Since the name of a destination variable was passed via `dest`, the following attribute lookup suffices: `"not pytest.config.option.longrun,"`. Neat-o, eh? – Cecil Curry Oct 21 '17 at 03:40
  • Excellent, thanks. Editing: no need to import pytest in `conftest.py`. – Jérôme May 10 '18 at 22:00
  • 3
    Any idea how to define `longrun` decorator in `conftest.py`? Also, "accessing pytest.config is discouraged" (https://github.com/pytest-dev/pytest/issues/1688#issuecomment-229477812). – Jérôme May 13 '18 at 22:03
  • 2
    This is old, see: https://stackoverflow.com/questions/51883573/using-a-command-line-option-in-a-pytest-skip-if-condition – SCGH Oct 28 '20 at 14:20
  • This doesn't work in >=5.0 [due to config being removed](https://stackoverflow.com/a/62770650/913098). Got a workaround? – Gulzar Feb 15 '22 at 14:55
  • Thanks. I've updated the text: the `skipif` string parameter is interpreted and can use `config`. – Roland Puntaier Feb 15 '22 at 17:48
16

try to decorate your test as @pytest.mark.longrun

in your conftest.py

def pytest_addoption(parser):
    parser.addoption('--longrun', action='store_true', dest="longrun",
                 default=False, help="enable longrundecorated tests")

def pytest_configure(config):
    if not config.option.longrun:
        setattr(config.option, 'markexpr', 'not longrun')
sax
  • 3,708
  • 19
  • 22
  • 2
    This will disable markers set with `pytest -m`. To avoid that, append `and not longrun` if `markexpr` already has a value. – Jess Jan 10 '19 at 22:38
  • Is `conftest.py` a file that `pytest` knows about? – Everett Sep 19 '19 at 16:10
  • 1
    @Everett yes it is the default pytest configuration file https://docs.pytest.org/en/2.7.3/plugins.html?highlight=re#conftest-py-plugins – sax Sep 26 '19 at 13:33
10

This is a slightly different way.

Decorate your test with @pytest.mark.longrun:

@pytest.mark.longrun
def test_something():
    ...

At this point you can run everything except tests marked with that using -m 'not longrun'

$ pytest -m 'not longrun'

or if you only want to run the longrun marked tests,

$ pytest -m 'longrun'

But, to make -m 'not longrun' the default, in pytest.ini, add it to addopts:

[pytest]
addopts =  
    -m 'not longrun'
    ...

If you want to run all the tests, you can do

$ pytest -m 'longrun or not longrun'
binaryfunt
  • 6,401
  • 5
  • 37
  • 59