I have seen from the pytest docs that we can apply multiple markers at once on the Class or module level. I didn't find documentation for doing it at the test function level. Has anybody done this before with success?
I would like to ideally do this as a list of markers as being done in the above doc for Classes, for example (quoting from the docs):
class TestClass:
pytestmark = [pytest.mark.webtest, pytest.mark.slowtest]
So, the pytest documentation talks about using pytestmark
to specify the markers at the class and module level. However, it doesn't talk about having something similar at the test function level. I would have to specify the markers individually on top of test functions to get them marked with each one of them. This makes the test code look a little clunky with the increasing number of markers on top of test functions.
test_example.py:
pytestmark = [class1, class2]
class TestFeature(TestCase):
@pytest.mark.marker1
@pytest.mark.marker2
@pytest.mark.marker3
def test_function(self):
assert True
Multiple custom markers can be registered, by defining each one in its own line, as shown in above example. You can ask which markers exist for your test suite - the list includes our just defined webtest and slow markers: $ pytest --markers @pytest. mark.
Automation Testing with Pytest To use markers, we have to import pytest module in the test file. We can define our own marker names to the tests and run the tests having those marker names. -m <markername> represents the marker name of the tests to be executed.
Parametrized tests The above decorator is a very powerful functionality, it permits to call a test function multiple times, changing the parameters input at each iteration.
@pytest. mark. parametrize allows one to define multiple sets of arguments and fixtures at the test function or class. pytest_generate_tests allows one to define custom parametrization schemes or extensions.
For functions you just repeat the decorator:
@pytest.mark.webtest
@pytest.mark.slowtest
def test_something(...):
...
If you want to reuse that for several tests you should remember that decorators are just functions returning decorated thing, so several decorators is just a composition:
def compose_decos(decos):
def composition(func):
for deco in reversed(decos):
func = deco(func)
return func
return composition
all_marks = compose_decos(pytest.mark.webtest, pytest.mark.slowtest)
@all_marks
def test_something(...):
...
Or you can use general purpose composition such as my funcy library has:
from funcy import compose
all_marks = compose(pytest.mark.webtest, pytest.mark.slowtest)
Note that this way you can compose any decorators, not only pytest marks.
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