Table of Contents
Introduction to Pytest Fixtures?
In pytest, a fixture is essentially a resource or piece of data that you set up ahead of the test start and remove once the tests are finished. Fixtures offer a reusable method of managing and organizing test setup and teardown code.
Functionality of Pytest Fixtures:
Setup and Teardown: Fixtures let you construct functions that, during the setup phase, create the required state for your tests and, during the teardown phase, remove that state. This guarantees that all tests begin in a known state and do not conflict with one another.
Reusability: Test modules or numerous tests can share the same fixes. This facilitates code reuse and streamlines test suite upkeep and updates.
Scope: Fixtures can be categorized according to their function, class, module, or session scope. This gives you the ability to schedule the fixture setup and teardown code according to the requirements of your tests.
Parametrization: Fixtures can be parametrized, which allows you to specify several sets of data for a single fixture. Your tests will be more comprehensive as a result of being able to execute the same test with various input values.
Pytest Environment setup
- Download and install Python as per your system’s operating system if python is not available in your system. Here is the link: https://www.python.org/downloads/ Please follow the steps which are coming during installation of the python application.
- There are multiple editor and IDE supported for python code development like PyCharm, Visual Studio Code, and Eclipse. Please use any one for your development.
- Install pytest framework from command line
# pip install -U pytest - Verify pytest installation by checking pytest version using command, # pytest –version
Defining pytest fixtures?
When you automate scripts, there are some pre-steps or setup code, like for browser application testing, where you need to login to the application. Then you do the action, like whatever the test steps, and verify the actions. At last, you need to tear down or clean up the environment, like before the start of the test so that other tests are not influenced by it.
#setup code or pre step before running a test
#Action
#Verify the action
#teardown or cleanup
So, to avoid the setup and teardown code in every test case, we can write a simple function with the setup and teardown code and call the function in every test cases.
For details understanding and usage, please visit https://docs.pytest.org/en/6.2.x/fixture.html
You need to simply create a function and decorate the function with ‘@pytest.fixture’.
import pytest
@pytest.fixture
def my_fixure():
#setup code or pre step before running a test
print("\nlogin")
yield
#teardown or cleanup
print("logoff")
def test_fixture_case1(my_fixure):
print("Browse Products")
@pytest.fixture
: This decorator marks the function as a fixture.- def my_fixure() This fixture functions contains the setup and teardown code separated by ‘yield’ keyword.
- To use the fixture function in each case, simply pass the fixture name as an argument in the test case.
- Now add another case that is not using the fixture.
def test_fixture_case2():
print("Browse Items")
- Now execute the script. You can check in the execution result that the first case is calling the setup and teardown code, but the second case is not calling those because defined fixtures is not used in this function. Below is the execution result:
C:\pytest>python -m pytest -s test_fixture.py
========================================================================= test session starts =========================================================================
platform win32 -- Python 3.8.2, pytest-8.1.1, pluggy-1.4.0
rootdir: C:\pytest
collected 2 items
test_fixture.py
login
Browse Products
.logoff
Browse Items
.
========================================================================== 2 passed in 0.02s ==========================================================================
Use of Conftest.py in PyTest Fixtures:
In pytest, conftest.py is a unique filename that facilitates the sharing and organization of fixtures, among several test files or directories. In the previous example, we needed to pass the fixture name as a parameter for every test case. We can avoid this by defining the fixture in the conftest.py file.
All test files and directories in the same directory and its subdirectories will automatically find and have access to the fixtures that are mentioned in the ‘Conftest.py’ file. By doing this, you may eliminate code duplication across several test files and centralize fixture definitions.
Scope: Pytest fixtures:
Fixtures in Pytest can have several scopes that control how long they last and when they are assembled and disassembled. Fixture scopes that are offered include:
Function Scope: By default, this is the scope. For every test function that utilizes it, a fixture with a function scope is assembled and disassembled once. This ensures that every test executes independently because a new fixture is produced for every test function.
Class Scope: For every test class that utilizes it, a fixture with class scope is assembled and disassembled once. This indicates that all test methods in the same test class share the same fixture. When putting up pricey resources that can be utilized for several assessments within a class, this can be helpful.
Module Scope: For every test module that utilizes it, a fixture with a module scope is assembled and disassembled once. This indicates that every test function in the same module uses the same fixture. This can be helpful for configuring resources that are costly to produce and can be used to several tests inside a module.
Package Scope: For every test package that utilizes it, a fixture with a package scope is assembled and disassembled once. This indicates that every test module in the same package uses the same fixture. This can be helpful when configuring resources that are costly to produce and can be used to several tests inside of a package.
To define the scope, you need to pass the scope as a parameter, like @pytest.fixture(scope=”class”)/@pytest.fixture(scope=”module”) etc.
Built-in PyTest Fixtures:
Pytest provides many built-in fixtures, which are helpful in testing situations. It is not necessary to describe these fixtures explicitly because they are easily accessible. Here are a few of the built-in fixtures that are most frequently used:
request: This fixture offers functionality and details about the test that is presently underway. It gives you access to the test function’s name, module, and request context, among other properties.
pytestconfig: The pytest configuration can be accessed using this fixture. During testing, it enables you to programmatically change the settings and obtain configuration values.
tmpdir: A temporary directory specific to every test function is provided by this fixture. During testing, it is frequently used to create and manipulate temporary files and folders.
tmp_path: This fixture creates a temporary directory, just like tmpdir, but it also returns a pathlib.in place of a py.path object with a path object.
capsys: The test function’s stdout and stderr output are captured by this fixture. It offers ways to access and work with the output that has been captured.
monkeypatch: During testing, you can dynamically change functions, classes, or attributes with this fixture.
Conclusion:
Finally, pytest fixtures offer an effective way to handle test setup and teardown code in a reusable and adaptable way. All things considered, pytest fixtures are an effective feature that enhances the scalability, versatility, and simplicity. You may create clear, modular, and maintainable tests that precisely confirm the behavior of your code by making good use of fixtures.
You may like the blog post on pytest marker https://dasfascination.com/enhance-testing-pytest-marker/