Using A Command-line Option In A Pytest Skip-if Condition
Solution 1:
Looks like true way to Control skipping of tests according to command line option is mark tests as skip dynamically:
- add option using pytest_addoption hook like this:
defpytest_addoption(parser):
parser.addoption(
"--runslow", action="store_true", default=False, help="run slow tests"
)
- Use pytest_collection_modifyitems hook to add marker like this:
def pytest_collection_modifyitems(config, items):
ifconfig.getoption("--runslow"):
# --runslow given in cli: do not skip slow testsreturn
skip_slow = pytest.mark.skip(reason="need --runslow option to run")
for item in items:
if"slow"in item.keywords:
item.add_marker(skip_slow)
- Add mark to you test:
@pytest.mark.slowdeftest_func_slow():
pass
If you want to use the data from the CLI in a test, for example, it`s credentials, enough to specify a skip option when retrieving them from the pytestconfig:
- add option using pytest_addoption hook like this:
defpytest_addoption(parser):
parser.addoption(
"--credentials",
action="store",
default=None,
help="credentials to ..."
)
- use skip option when get it from pytestconfig
@pytest.fixture(scope="session")defsuper_secret_fixture(pytestconfig):
credentials = pytestconfig.getoption('--credentials', skip=True)
...
- use fixture as usual in you test:
deftest_with_fixture(super_secret_fixture):
...
In this case you will got something like this it you not send --credentials
option to CLI:
Skipped: no'credentials' option found
It is better to use _pytest.config.get_config instead of deprecated pytest.config If you still wont to use pytest.mark.skipif like this:
@pytest.mark.skipif(not _pytest.config.get_config().getoption('--credentials'), reason="--credentials was not specified")
Solution 2:
The problem with putting global code in fixtures is that markers are evaluated before fixtures, so when skipif
is evaluated, configInfo
didn't run yet and pytest.global_env
will be empty. I'd suggest to move the configuration code from the fixture to pytest_configure
hook:
# conftest.pyimport configparser
import pytest
defpytest_addoption(parser):
parser.addoption('--ENV')
defpytest_configure(config):
environment = config.getoption('--ENV')
pytest.global_env = environment
...
The configuration hook is guaranteed to execute before the tests are collected and the markers are evaluated.
Is there a better way to be trying this than the
pytest_namespace
?
Some ways I know of:
- Simply assign a module variable in
pytest_configure
(pytest.foo = 'bar'
, like I did in the example above). Use the
config
object as it is shared throughout the test session:defpytest_configure(config): config.foo = 'bar'@pytest.fixturedefsomefixture(pytestconfig): assert pytestconfig.foo == 'bar'deftest_foo(pytestconfig): assert pytestconfig.foo == 'bar'
Outside of the fixtures/tests, you can access the config via
pytest.config
, for example:@pytest.mark.skipif(pytest.config.foo == 'bar', reason='foo is bar')deftest_baz(): ...
Use caching; this has an additional feature of persisting data between the test runs:
defpytest_configure(config): config.cache.set('foo', 'bar') @pytest.fixturedefsomefixture(pytestconfig): assert pytestconfig.cache.get('foo', None) deftest_foo(pytestconfig): assert pytestconfig.cache.get('foo', None) @pytest.mark.skipif(pytest.config.cache.get('foo', None) == 'bar', reason='foo is bar')deftest_baz(): assertTrue
When using 1. or 2., make sure you don't unintentionally overwrite pytest
stuff with your own data; prefixing your own variables with a unique name is a good idea. When using caching, you don't have this problem.
Post a Comment for "Using A Command-line Option In A Pytest Skip-if Condition"