Bird
Raised Fist0
PyTesttesting~15 mins

Fixture scope (function, class, module, session) in PyTest - Build an Automation Script

Choose your learning style10 modes available
Verify pytest fixture scopes function, class, module, and session
Preconditions (2)
Step 1: Create a fixture with scope='function' that prints 'Setup function' when used
Step 2: Create a fixture with scope='class' that prints 'Setup class' when used
Step 3: Create a fixture with scope='module' that prints 'Setup module' when used
Step 4: Create a fixture with scope='session' that prints 'Setup session' when used
Step 5: Write test functions and test classes that use these fixtures
Step 6: Run pytest with the test file
Step 7: Observe the order and number of times each fixture setup message is printed
✅ Expected Result: The 'Setup function' message prints before each test function that uses the function-scoped fixture. The 'Setup class' message prints once per test class that uses the class-scoped fixture. The 'Setup module' message prints once per module. The 'Setup session' message prints only once for the entire test session.
Automation Requirements - pytest
Assertions Needed:
Verify that function-scoped fixture setup runs before each test function
Verify that class-scoped fixture setup runs once per test class
Verify that module-scoped fixture setup runs once per module
Verify that session-scoped fixture setup runs once per test session
Best Practices:
Use pytest fixtures with proper scope parameter
Use print statements or logging to track fixture setup calls
Use pytest's capsys fixture to capture output for assertions
Structure tests to clearly separate function, class, module, and session scope usage
Automated Solution
PyTest
import pytest

setup_calls = {
    'function': 0,
    'class': 0,
    'module': 0,
    'session': 0
}

@pytest.fixture(scope='function')
def func_scope_fixture():
    setup_calls['function'] += 1
    print('Setup function')
    yield

@pytest.fixture(scope='class')
def class_scope_fixture():
    setup_calls['class'] += 1
    print('Setup class')
    yield

@pytest.fixture(scope='module')
def module_scope_fixture():
    setup_calls['module'] += 1
    print('Setup module')
    yield

@pytest.fixture(scope='session')
def session_scope_fixture():
    setup_calls['session'] += 1
    print('Setup session')
    yield

# Test functions using function and module scope

def test_func1(func_scope_fixture, module_scope_fixture, session_scope_fixture):
    assert setup_calls['function'] >= 1
    assert setup_calls['module'] == 1
    assert setup_calls['session'] == 1


def test_func2(func_scope_fixture, module_scope_fixture, session_scope_fixture):
    assert setup_calls['function'] >= 2
    assert setup_calls['module'] == 1
    assert setup_calls['session'] == 1

# Test class using class and module scope

class TestClass:
    def test_method1(self, class_scope_fixture, module_scope_fixture, session_scope_fixture):
        assert setup_calls['class'] == 1
        assert setup_calls['module'] == 1
        assert setup_calls['session'] == 1

    def test_method2(self, class_scope_fixture, module_scope_fixture, session_scope_fixture):
        assert setup_calls['class'] == 1
        assert setup_calls['module'] == 1
        assert setup_calls['session'] == 1

This test script defines four fixtures with different scopes: function, class, module, and session.

Each fixture increments a counter and prints a setup message when it runs.

Test functions and a test class use these fixtures to verify how many times each setup runs.

Assertions check that function-scoped fixture runs before each test function, class-scoped fixture runs once per class, module-scoped fixture runs once per module, and session-scoped fixture runs once per entire test session.

This approach uses counters and assertions to confirm fixture scope behavior clearly and simply.

Common Mistakes - 4 Pitfalls
Using function scope fixture but expecting it to run only once
Not yielding in fixtures and missing teardown steps
{'mistake': 'Using print statements without capturing output in tests', 'why_bad': 'Print output is not captured by default, so assertions on printed messages fail.', 'correct_approach': "Use pytest's capsys fixture to capture and assert printed output."}
Defining fixtures inside test classes
Bonus Challenge

Now add data-driven testing with 3 different inputs to test functions using the function-scoped fixture

Show Hint

Practice

(1/5)
1. What does the function scope mean for a pytest fixture?
easy
A. The fixture runs once per entire test session.
B. The fixture runs once per test class.
C. The fixture runs once per test module.
D. The fixture runs once per test function.

Solution

  1. Step 1: Understand fixture scopes

    Pytest fixtures can have different scopes controlling how often they run.
  2. Step 2: Define function scope meaning

    Function scope means the fixture runs before each test function and tears down after it.
  3. Final Answer:

    The fixture runs once per test function. -> Option D
  4. Quick Check:

    function scope = runs per test function [OK]
Hint: Function scope means run before every test function [OK]
Common Mistakes:
  • Confusing function scope with class or module scope
  • Thinking function scope runs once per class
  • Assuming function scope runs once per session
2. Which of the following is the correct way to set a pytest fixture with module scope?
easy
A. @pytest.fixture(scope='module')
B. @pytest.fixture(scope='function')
C. @pytest.fixture(scope='class')
D. @pytest.fixture(scope='session')

Solution

  1. Step 1: Recall fixture scope syntax

    To set a fixture scope, use @pytest.fixture(scope='scope_name').
  2. Step 2: Match scope name for module

    The correct scope name for module is 'module'.
  3. Final Answer:

    @pytest.fixture(scope='module') -> Option A
  4. Quick Check:

    module scope syntax = scope='module' [OK]
Hint: Use scope='module' to run fixture once per file [OK]
Common Mistakes:
  • Using 'session' instead of 'module' for module scope
  • Forgetting to add scope parameter
  • Using incorrect quotes or misspelling scope
3. Given this pytest code snippet, how many times will setup_db run?
import pytest

@pytest.fixture(scope='class')
def setup_db():
    print('Setup DB')

class TestA:
    def test_1(self, setup_db):
        pass
    def test_2(self, setup_db):
        pass

class TestB:
    def test_3(self, setup_db):
        pass
medium
A. 1 time
B. 3 times
C. 2 times
D. 4 times

Solution

  1. Step 1: Understand class scope behavior

    Fixture with class scope runs once per test class, before any tests in that class.
  2. Step 2: Count test classes using the fixture

    There are two test classes: TestA and TestB, each uses setup_db fixture.
  3. Step 3: Calculate total runs

    setup_db runs once for TestA and once for TestB, total 2 times.
  4. Final Answer:

    2 times -> Option C
  5. Quick Check:

    class scope = once per class, 2 classes = 2 runs [OK]
Hint: Class scope runs once per test class [OK]
Common Mistakes:
  • Counting runs per test method instead of per class
  • Confusing class scope with function scope
  • Ignoring multiple test classes
4. Identify the error in this pytest fixture usage:
import pytest

@pytest.fixture(scope='modul')
def setup_env():
    pass

def test_example(setup_env):
    assert True
medium
A. Missing @pytest.mark.usefixtures decorator.
B. Typo in scope value causes fixture not to run.
C. Fixture function must return a value.
D. Test function missing parentheses.

Solution

  1. Step 1: Check fixture scope spelling

    The scope value 'modul' is misspelled; correct is 'module'.
  2. Step 2: Understand effect of typo

    Pytest will not recognize the scope and may default or error, causing fixture not to run properly.
  3. Final Answer:

    Typo in scope value causes fixture not to run. -> Option B
  4. Quick Check:

    Scope must be spelled correctly [OK]
Hint: Check scope spelling carefully to avoid errors [OK]
Common Mistakes:
  • Assuming fixture must return a value
  • Confusing fixture decorator with marker
  • Ignoring spelling errors in parameters
5. You want a pytest fixture to initialize a database connection once before all tests in multiple modules run, and close it after all tests finish. Which scope should you use and why?
hard
A. Use session scope to share across all tests in the run.
B. Use function scope to isolate each test.
C. Use module scope to share per file.
D. Use class scope to share per test class.

Solution

  1. Step 1: Understand the requirement

    The database connection should be initialized once before all tests in multiple modules and closed after all tests.
  2. Step 2: Match scope to requirement

    Session scope runs once per entire test session, perfect for setup/teardown across all modules.
  3. Final Answer:

    Use session scope to share across all tests in the run. -> Option A
  4. Quick Check:

    Session scope = once per test run [OK]
Hint: Session scope runs once for all tests in the run [OK]
Common Mistakes:
  • Choosing function or class scope which run too often
  • Using module scope which limits to one file
  • Not matching scope to resource lifetime
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard