I have a fixture in conftest.py
with a function scope.
@pytest.fixture()
def registration_setup(
test_data, # fixture 1
credentials, # fixture 2
deployment # fixture 3
deployment_object # fixture 4
):
# pre-test cleanup
do_cleanup()
yield
# post-test cleanup
do_cleanup()
I use it in a test class like this:
class TestClass:
@pytest.fixture(autouse=True)
def _inventory_cleanup(self, registration_setup):
log('Cleanup Done!')
def test_1():
...
def test_2():
...
def test_3():
...
Now I want to create a new test class where I run the registartion_setup
fixture once for the entire class. The desired behaviour here is, First the pre-test cleanup executes and then all the tests in the new test class execute, followed by the post-test cleanup.
How can I achieve this, thanks for the help.
CodePudding user response:
Option 1
You can use the same approach you did on your other test class, but set the fixture scope to class
:
class TestClass:
@pytest.fixture(scope='class', autouse=True)
def _inventory_cleanup(self, registration_setup):
log('Cleanup Done!')
def test_1():
...
def test_2():
...
def test_3():
...
But you will then need to change the scope of the fixture registration_setup
to class
to avoid a ScopeMismatch
error.
Option 2
To keep using it with a function
scope, I suggest having two fixtures with the same behavior, but with different scopes, like this:
@pytest.fixture()
def registration_setup_for_function(
test_data, # fixture 1
credentials, # fixture 2
deployment # fixture 3
deployment_object # fixture 4
):
# pre-test cleanup
do_cleanup()
yield
# post-test cleanup
do_cleanup()
@pytest.fixture(scope='class')
def registration_setup_for_class(
test_data, # fixture 1
credentials, # fixture 2
deployment # fixture 3
deployment_object # fixture 4
):
# pre-test cleanup
do_cleanup()
yield
# post-test cleanup
do_cleanup()
If your other fixtures 1, 2, 3 and 4 have function
scope, you will have to change them also.
Option 3
If you don't want to have two identical fixtures with different scopes, you can do something like this:
In a conftest.py
file in the project root:
def pytest_configure(config):
config.first_test_executed = False
Then, wherever you have your fixture:
@pytest.fixture()
def registration_setup(
test_data, # fixture 1
credentials, # fixture 2
deployment, # fixture 3
deployment_object, # fixture 4
request # Note the request fixture here
):
if 'TestClass' in request.node.nodeid:
if not request.config.first_test_executed:
# pre-test cleanup
do_cleanup()
yield
# post-test cleanup
do_cleanup()
request.config.first_test_executed = True
else:
# pre-test cleanup
do_cleanup()
yield
# post-test cleanup
do_cleanup()
I know it is still a bit repeated, but this way your tests inside the class will call the registration_setup
fixture only once for the whole class, while other tests will call it always. Maybe you will find a better way knowing this now.
More info on the documentation:
Fixtures can introspect the requesting test context