🌐
Real Python
realpython.com › pytest-python-testing
pytest Tutorial: Effective Python Testing – Real Python
December 8, 2024 - Master pytest with this hands-on tutorial. Learn fixtures, parametrize, marks, and plugins to write fast, effective Python test suites.
🌐
pytest
docs.pytest.org › en › stable › explanation › goodpractices.html
Good Integration Practices - pytest documentation
[pytest] strict = true strict_parametrization_ids = false · On this page · Good Integration Practices · Install package with pip · Conventions for Python test discovery · Choosing a test layout · Tests outside application code · Tests as part of application code ·
🌐
Semaphore
semaphore.io › home › testing python applications with pytest
Testing Python Applications with Pytest - Semaphore Tutorial
April 3, 2024 - Fixture functions are created by marking them with the @pytest.fixture decorator. Test functions that require fixtures should accept them as arguments. For example, for a test to receive a fixture called wallet, it should have an argument with the fixture name, i.e. wallet. Let’s see how this works in practice...
🌐
pytest
docs.pytest.org
pytest documentation
Pytest Plugin List · Explanation · Anatomy of a test · About fixtures · Good Integration Practices · pytest import mechanisms and sys.path/PYTHONPATH · Typing in pytest · CI Pipelines · Flaky tests · Examples and customization tricks · Demo of Python failure reports with pytest ·
🌐
pytest
docs.pytest.org › en › 7.1.x › explanation › goodpractices.html
Good Integration Practices — pytest documentation
You can use namespace packages (PEP420) for your application but pytest will still perform test package name discovery based on the presence of __init__.py files. If you use one of the two recommended file system layouts above but leave away the __init__.py files from your directories, it should ...
🌐
TutorialsPoint
tutorialspoint.com › pytest › index.htm
Pytest Tutorial
It offers features like fixtures, parameterized tests, and detailed error reporting. With Pytest, you can efficiently test your code and ensure its reliability.
🌐
GeeksforGeeks
geeksforgeeks.org › python › getting-started-with-pytest
Getting Started with Pytest - GeeksforGeeks
July 23, 2025 - In this example, we first imported the Pytest module. After that we have defined a function func(x). In this function, it adds 5 to x and returns the result. Then, we defined another function named test_method. It uses an assert statement to check whether the result of func(3) is equal to 8.
Find elsewhere
🌐
pytest
docs.pytest.org › en › stable › getting-started.html
Get Started - pytest documentation
Having each test share the same class instance would be very detrimental to test isolation and would promote poor test practices. This is outlined below: # content of test_class_demo.py class TestClassDemoInstance: value = 0 def test_one(self): self.value = 1 assert self.value == 1 def test_two(self): assert self.value == 1 · $ pytest -k TestClassDemoInstance -q .F [100%] ================================= FAILURES ================================= ______________________ TestClassDemoInstance.test_two ______________________ self = <test_class_demo.TestClassDemoInstance object at 0xdeadbeef0002
🌐
TestDriven.io
testdriven.io › blog › pytest-for-beginners
Pytest for Beginners | TestDriven.io
September 28, 2022 - This article looks at the very basics of using pytest for testing Python code.
🌐
LambdaTest
lambdatest.com › learning hub › what is pytest: complete guide with best practices
What Is pytest: A Complete pytest Tutorial With Best Practices
November 25, 2025 - It provides fixtures for configuring an instance of the Selenium WebDriver and interacting with the WebElements in the DOM. Here we use version >= 4.0.0. We are currently utilizing 'pytest-selenium' version 4.0.0 or later. Having covered the fundamental aspects of setting up Selenium in Python, it's time to delve into practical test scenarios.
🌐
Medium
medium.com › @adocquin › mastering-unit-tests-in-python-with-pytest-a-comprehensive-guide-896c8c894304
Mastering Unit Tests in Python with pytest: A Comprehensive Guide
September 26, 2023 - Learn Python unit testing with pytest. Discover assertions, mocking, fixtures to improve your code's quality, maintainability, and robustness.
🌐
Real Python
realpython.com › quizzes › test-driven-development-pytest
Test-Driven Development With pytest Quiz – Real Python
Test your TDD skills with pytest. Practice writing unit tests, following pytest conventions, and measuring code coverage.
🌐
GitHub
github.com › Maddosaurus › pytest-practice
GitHub - Maddosaurus/pytest-practice: Example repo containing Python testing best practices I've found for myself
Example repo containing Python testing best practices I've found for myself. It is a combination of pytest, unittest.mock and serves as a best practice collection and playground to test new things.
Author   Maddosaurus
🌐
DataCamp
datacamp.com › tutorial › pytest-tutorial-a-hands-on-guide-to-unit-testing
How to Use Pytest for Unit Testing | DataCamp
July 15, 2022 - Pytest is extremely easy to learn: ... mastering the framework. Tests using pytest are Python functions with “test_” prepended or “_test” appended to the function's name - although you can use a class to group multiple ...
Top answer
1 of 3
9

The best practice for setup and teardown that run once during whole test run is usage of "session" scope fixture. You should not use hooks for it.

In your case I believe you just need to create conftest.py file in your tests root directory. Then you add some function that you must decorate with @pytest.fixture(scope="session").

Your setup and teardown must be separated with yield statement like this:

import pytest


@pytest.fixture(scope="session")
def some_function_name():
    print("this is setup")
    yield
    print("this is teardown")

Do not forget to request this fixture in every test that needs these setup and teardown. If you need it for all of your tests without any exceptions then you may use flag autouse=True as pytest.fixture argument. However, I do not recommend to use it because it makes your code a bit harder to debug.

Please note that it will be executed only once per whole test run. That's because we use scope "session".

You can read more about fixture scopes here: https://docs.pytest.org/en/6.2.x/fixture.html#scope-sharing-fixtures-across-classes-modules-packages-or-session

UPD:

pytest test_2.py -s

In pytest_addoption

In pytest_configure   
                      
In pytest_sessionstart
==== test session starts ===
platform win32 -- Python 3.11.3, pytest-7.3.1, pluggy-1.0.0
rootdir: C:\repos\pytest_imports
configfile: pyproject.toml
collected 2 items                                                                                                                                                                                                                       

test_2.py
Beginning of fixture

Between test

test1
.
Between test

test2
.
End of fixture

In pytest_sessionfinish


2 of 3
2

tl;dr: Best practice-wise, according to the PyTest documentation (and also how I do it in all my pytest implementation as well...), is to use the yield fixture. Referred in the docs here, and SO as well.


PyTest recommendation

Reference: https://docs.pytest.org/en/latest/how-to/fixtures.html#teardown-cleanup-aka-fixture-finalization

You use the fixtures for reusability. Although what pl3b said is the better choice, by using the conftest.py, for usage in other test modules, I am showing below, the snippet if you're to try it out in only one module.

There's also the advantage of this fixture, to use specific reusable functions for certain tests. In this example, test_2 and test_3 will use the add_space fixture, and test_1 doesn't.

# ./test_playground.py

import pytest
import inspect

@pytest.fixture(scope="session", autouse=True)
def print_beginning_of_session():
    print("I begin here")
    yield
    print("I end here")

@pytest.fixture(scope="function")
def add_space():
    print("--*--")
    yield
    print("--##--")

def test_no_1():
    print(f"this is {inspect.currentframe().f_code.co_name}")

def test_no_2(add_space):
    print(f"this is {inspect.currentframe().f_code.co_name}")

def test_no_3(add_space):
    print(f"this is {inspect.currentframe().f_code.co_name}")

XUnit-Style

Reference: https://docs.pytest.org/en/stable/how-to/xunit_setup.html

The disadvantage that I see in my example here, in comparison to the fixture-stype above, is that I can't customize the setup_function to only run for test_2 and test_3. There is a way, by splitting it up in test classes, tbf, but it does get a slightly bit more complicated while writing.

# ./test_playground.py

import inspect

# There isn't a setup_session() as far as I understand, so we use module here instead, for a "one-time" start.

def setup_module():
    print("I begin here")

def teardown_module():
    print("I end here")

def setup_function():
    print("--***--")

def teardown_function():
    print("--###--")

def test_no_1():
    print(f"this is {inspect.currentframe().f_code.co_name}")

def test_no_2():
    print(f"this is {inspect.currentframe().f_code.co_name}")

def test_no_3():
    print(f"this is {inspect.currentframe().f_code.co_name}")

Output of both styles

FYI: Please forgive the output, it's not really readable for debugging, but it does show where things are. I used the arguments ['-s', '-vv']

============================= test session starts =============================
test_playground.py::test_no_1 I begin here
this is test_no_1
PASSED
test_playground.py::test_no_2 --*--
this is test_no_2
PASSED--##--

test_playground.py::test_no_3 --*--
this is test_no_3
PASSED--##--
I end here
🌐
Better Stack
betterstack.com › community › guides › testing › pytest-guide
A Beginner's Guide to Unit Testing with Pytest | Better Stack Community
January 27, 2026 - Learn how to write clean, concise, and effective Python tests using Pytest's intuitive syntax, fixtures, parametrization, and rich plugin ecosystem
🌐
GitHub
gist.github.com › devops-school › c0b260e7b845dff98556511071d0bf7c
Complete Guide to Pytest: From Basics to Advanced · GitHub
This step-by-step guide covers everything you need to get started with Pytest and progress to advanced testing capabilities. Pytest is a versatile tool that can handle a variety of testing scenarios, from simple unit tests to complex integration tests.
🌐
ITNEXT
itnext.io › how-to-use-pytest-including-real-examples-and-best-practices-11073e4fd514
How To Use PyTest including Real Examples And Best Practices | by Eric Sales De Andrade | ITNEXT
May 10, 2022 - Being a self-learned developer myself, it’s hard to pick up best practices without spending much time in the industry, or having a mentor. This blog will teach you how to write Python Unit tests using the PyTest framework and maximise coverage, mock external APIs and Services, and include testing as part of your CI/CD pipeline.