[Pytest] Fixture

Rex Chiang
2 min readFeb 5, 2023

Fixtures are functions that run before or after tests, like setup or teardown. Fixtures are used for data configuration, initialization, database connection/disconnection, etc.

Scope

  1. Function (Run once per test)
  • Function base test cases
import pytest

@pytest.fixture(scope="function")
def init_funtion():
print("INIT")

def test_case1(init_funtion):
print("Case1")

def test_case2(init_funtion):
print("Case2")

"""
Result
"""
# INIT
# Case1
# INIT
# Case2
  • Class base test cases
import pytest

@pytest.fixture(scope="function")
def init_funtion():
print("INIT")

class TestCases():
def test_case1(self, init_funtion):
print("Case1")

def test_case2(self, init_funtion):
print("Case2")

"""
Result
"""
# INIT
# Case1
# INIT
# Case2

2. Class (Run once per class of tests)

  • Function base test cases
import pytest

@pytest.fixture(scope="class")
def init_funtion():
print("INIT")

def test_case1(init_funtion):
print("Case1")

def test_case2(init_funtion):
print("Case2")

"""
Result
"""
# INIT
# Case1
# Case2
  • Class base test cases
import pytest

@pytest.fixture(scope="class")
def init_funtion():
print("INIT")

class TestCases():
def test_case1(self, init_funtion):
print("Case1")

def test_case2(self, init_funtion):
print("Case2")

"""
Result
"""
# INIT
# Case1
# Case2
  • Function base and Class base test cases
import pytest

@pytest.fixture(scope="class")
def init_funtion():
print("INIT")

def test_case1(init_funtion):
print("Case1")

class TestCases():
def test_case2(self, init_funtion):
print("Case2")

"""
Result
"""
# INIT
# Case1
# INIT
# Case2

3. Module (Run once per module)

import pytest

@pytest.fixture(scope="module")
def init_funtion():
print("INIT")

def test_case1(init_funtion):
print("Case1")

class TestCases():
def test_case2(self, init_funtion):
print("Case2")

"""
Result
"""
# INIT
# Case1
# Case2

4. Session (Run once per session)

  • Set fixture in conftest.py, and can run globally.
  • conftest.py
# conftest.py

import pytest

@pytest.fixture(scope="session")
def init_funtion():
print("INIT")
  • test_case1.py
# test_case1.py

def test_case1(init_funtion):
print("Case1")
  • test_case2.py
# test_case2.py

class TestCases():
def test_case2(self, init_funtion):
print("Case2")
  • Result
""" 
Result
"""
# INIT
# Case1
# Case2

Setup / Teardown

  1. yield
  • The part before yield will execute at the beginning of test.
  • The part after yield will execute at the end of test.
import pytest

@pytest.fixture()
def fixture_funtion():
print("START")
yield
print("FINISH")

class TestCases():
def test_case1(self, fixture_funtion):
print("Case1")

"""
Result
"""
# START
# Case1
# FINISH

2. addfinalizer

  • Same as yield, but need to register teardown function.
import pytest

@pytest.fixture()
def fixture_funtion(request):
print("START")

def final_function():
print("FINISH")

request.addfinalizer(final_function)

class TestCases():
def test_case1(self, fixture_funtion):
print("Case1")

"""
Result
"""
# START
# Case1
# FINISH

Parametrizing

  • If test cases need duplicate parameters, we can pass parameters through request.
import pytest

@pytest.fixture(params=[1, 2])
def fixture_funtion(request):
print("START")
yield request.param

class TestCases():
def test_case1(self, fixture_funtion):
print("Case1")
print(fixture_funtion)

def test_case2(self, fixture_funtion):
print("Case2")
print(fixture_funtion)

"""
Result
"""
# START
# Case1
# 1
# START
# Case1
# 2
# START
# Case2
# 1
# START
# Case2
# 2

Usage

  1. Basic
import pytest

@pytest.fixture()
def init_funtion():
print("INIT")

class TestCases():
def test_case1(self, init_funtion):
print("Case1")

2. Autouse

import pytest

@pytest.fixture(autouse=True)
def init_funtion():
print("INIT")

class TestCases():
def test_case1(self):
print("Case1")

3. Pytest Mark

import pytest

@pytest.fixture()
def init_funtion():
print("INIT")

@pytest.mark.usefixtures("init_funtion")
class TestCases():
def test_case1(self):
print("Case1")

--

--