I am trying to use a pytest fixture (scope=module) in a class skipif decorator, but I am getting an error saying the fixture is not defined. Is this possible?
conftest.py has a fixture with module scope called 'target' that returns a CurrentTarget object. The CurrentTarget object has a function isCommandSupported. test_mytest.py has a class Test_MyTestClass that contains a dozen test functions. I want to skip all the tests in Test_MyTestClass based on if the fixture target.isCommandSupported so I decorate Test_MyTestClass with skipif like:
@pytest.mark.skipif(not target.isCommandSupprted('commandA), reason=command not supported')
class Test_MyTestClass:
...
I get this error: NameError: name 'target' is not defined
If I try:
@pytest.mark.skipif(not pytest.config.getvalue('tgt').isCommandSupprted('commandA), reason=command not supported')
class Test_MyTestClass:
...
I get this error: AttributeError: 'function' object has no attribute 'isCommandSupprted'
The reason you get an error in the first case is that pytest injects fixtures, so they become available in your test functions via function parameters. They are never imported into higher scope.
The reason you get the AttributeError is that fixtures are functions and are evaluated at first (or each) use. So, when you get it through pytest.config
it's still a function. This is the same reason the other answer will fail - if you import it, you're importing the fixture function, not it's result.
There is no direct way of doing what you want, but you can work around it with an extra fixture:
@pytest.fixture(scope='module')
def check_unsupported(target):
if not target.isCommandSupported('commandA'):
pytest.skip('command not supported')
@pytest.mark.usefixtures('check_unsupported')
def test_one():
pass
def test_two(check_unsupported):
pass
You can import target
from conftest like so:
from conftest import target
Then, you can use it in pytest.mark.skipif
as you were intending in your example.
@pytest.mark.skipif(not target.isCommandSupported('commandA'), reason='command not supported')
def Test_MyTestClass:
If you needed to repeat the same pytest.mark.skipif
logic across several tests and wanted to avoid copy-pasting, a simple decorator will help:
check_unsupported = pytest.mark.skipif(not target.isCommandSupported('commandA'),
reason='command not supported')
@check_unsupported
def test_one():
pass
@check_unsupported
def test_two():
pass
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With