CIsForCookies
CIsForCookies

Reputation: 12807

pytest: Using a "session" scope fixture along with default scope fixtures

I'm building a pytest test suite, testing a package I'm building. The tests should verify some things about the pkg, such as minor functionality checks, minor sanity checks and so on. Some of the checks are done pre-install and some post-install (example code):


Tests file:

import pytest

class PreInstallTests(object):
    def test_foo(self, bar):
        assert bar > 2

class PostInstallTests(object):
    def test_goo(self, baz):
        assert baz < 3

    def test_hoo(self, baz):
        assert baz > 1

conftest file:

import pytest
@pytest.fixture
def tmp_dir():
    os.mkdir('tmp')
    yield
    shutil.rmtree('tmp')

@pytest.fixture
def bar(tmp_dir):
    yield 3

@pytest.fixture
def baz(install, tmp_dir):
    yield 2

@pytest.fixture(scope='session')
def install():
    # installs the pkg... (takes a lot of time)

As can be seen here, I have 2 post-install tests, each one using a fixture called baz that uses the install fixture. I want to have only one installation, and either use the same installation for all post-install-tests (not ideal, but the tests are minimal, and I don't want to waste much time on re-installing currently).

Using the "scope" session parameter can solve my problem, but that would prohibit me from using any other fixture, such as "tmp_dir" (which represents a fixture that I need, and must stay default-scoped...)

How can I achieve one install for all tests, and still use my other fixtures, whom I want to leave with their default scope?

I thought of making the install an autouse fixture, but I actually need it to be called after some of the other fixtures that are currently default scoped, and should stay that way

Upvotes: 3

Views: 2749

Answers (2)

msudder
msudder

Reputation: 512

as described in ScopeMismatch on using session scoped fixture with pytest-mozwebqa plugin for py.test

use the session scoped tmpdir_factory for install and remove tmp_dir, consume builtin tmpdir, since pytest 3.x.

Upvotes: 0

Gabriel Cappelli
Gabriel Cappelli

Reputation: 4170

Only solution I could think of is to have a flag controlling if you've already run the installation code, then keep the fixture with default scope.


import pytest

installed = False

@pytest.fixture()
def install():
    global installed
    if not installed:
        print('installing')
        installed = True

Upvotes: 1

Related Questions