Zzzz code digger

More into pytest fixture scope

2021-10-12
Longxiang Lyu

  • problem: in a test file, some of the test cases want to share a fixture that does some environment setup that could be persistent across test cases, what scope should the fixture have?

  • test_func0 and test_func wants to share fixture fixture_a, so let’s define fixture_a as module level

from __future__ import print_function
import pytest


@pytest.fixture(scope="module")
def fixture_a():
    print()
    print("Module fixture setup")
    yield
    print()
    print("Module fixture teardown")


@pytest.fixture
def fixture_b():
    print()
    print("Function fixture setup")
    yield
    print()
    print("Function fixture teardown")


def test_func0(fixture_a):
    pass


def test_func1(fixture_b):
    pass


def test_func2(fixture_a, fixture_b):
    pass

  • output
$ pytest test_demo.py -s -v
============================================================================================== test session starts ==============================================================================================
platform linux2 -- Python 2.7.17, pytest-3.3.2, py-1.5.2, pluggy-0.6.0 -- /usr/bin/python2
cachedir: .cache
rootdir: /home/lolv/workspace/demo, inifile:
collected 3 items

test_demo.py::test_func0
Module fixture setup
PASSED                                                                                                                                                                           [ 33%]
test_demo.py::test_func1
Function fixture setup
PASSED                                                                                                                                                                           [ 66%]
Function fixture teardown

test_demo.py::test_func2
Function fixture setup
PASSED                                                                                                                                                                           [100%]
Function fixture teardown

Module fixture teardown


=========================================================================================== 3 passed in 0.01 seconds ============================================================================================
  • the module level fixture fixture_a will be created/called by test_func0 and destroyed after test_func2
  • the side effect is that, even test_func1 doesn’t explicitly calls fixture_a, if fixture_a does some test environment modification, it might have influence on test_func1 as it is executed during the lifetime of fixture_a.
  • the definition of fixture scope from pytest document:
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.
  • so to eliminate the might-have influence of fixture_a over test_func1, we might reorder the test function definition as the following so test_func will be executed before the creation/call of fixture_a
def test_func1(fixture_b):
    pass


def test_func0(fixture_a):
    pass


def test_func2(fixture_a, fixture_b):
    pass

references

  • https://docs.pytest.org/en/6.2.x/fixture.html

Similar Posts

Comments