Pytest "run-around-tests" fixture to run only once before all tests in a class Pytest "run-around-tests" fixture to run only once before all tests in a class selenium selenium

Pytest "run-around-tests" fixture to run only once before all tests in a class


You have to adapt the fixture scope to cache its results for all tests in test run (scope='session'), all tests in module (scope='module'), all tests in class (old unittest-style tests only, scope='class'), or for a single test (scope='function'; this the default one). Examples:

fixture function

@pytest.fixture(scope='session')def token():    return token_helper.get_api_access_token()class Tests(object):    def test_one(self, token):        ...    def test_two(self, token):        ...class OtherTests(object):    def test_one(self, token):        ...

The token will be calculated once when first requested and kept in cache throughout the whole test run, so all three tests Tests::test_one, Tests::test_two and OtherTests::test_one will share the same token value.

fixture class method

If you intend to write old-style test classes instead of test functions and want the fixture to be a class method (like it is in your code), note that you can only use the class scope, so that the fixture value is shared only between the tests in the class:

class TestStuff(object):    @pytest.fixture(scope='class')    def token(self):        return token_helper.get_api_access_token()    def test_one(self, token):        ...    def test_two(self, token):        ...

Stuff aside:

  1. pytest.yield_fixture is deprecated and replaced by pytest.fixture;
  2. you don't need to set autouse=True because you explicitly request the fixture in the test parameters. It will be called anyway.


You can add a scope="module" parameter to the @pytest.fixture.

According to pytest documentation:

Fixtures requiring network access depend on connectivity and areusually time-expensive to create. Extending the previous example, wecan add a scope="module" parameter to the @pytest.fixture invocationto cause a smtp_connection fixture function, responsible to create aconnection to a preexisting SMTP server, to only be invoked once pertest module (the default is to invoke once per test function).Multiple test functions in a test module will thus each receive thesame smtp_connection fixture instance, thus saving time. Possiblevalues for scope are: function, class, module, package or session.

# content of conftest.pyimport pytestimport smtplib@pytest.fixture(scope="module")def smtp_connection():    return smtplib.SMTP("smtp.gmail.com", 587, timeout=5)

Fixture scopes

Fixtures are created when first requested by a test, and are destroyed based on their scope:*

function: the default scope, the fixture is destroyed at the end of the test.

class: the fixture is destroyed during teardown of the last test in the class.

module: the fixture is destroyed during teardown of the last test in the module.

package: the fixture is destroyed during teardown of the last test in the package.

session: the fixture is destroyed at the end of the test session.

Note: Pytest only caches one instance of a fixture at a time, which means that when using a parametrized fixture, pytest may invoke a fixture more than once in the given scope.