Automated testing is a crucial part of software development, ensuring code reliability and stability. Among various testing frameworks available for Python, Pytest stands out due to its simplicity, flexibility, and powerful features. This guide will introduce you to Pytest, walk you through writing your first test case, and explore some of its advanced capabilities.
Why Choose Pytest?
Pytest is widely used because of its:
- Minimal Boilerplate: Requires less code to write effective tests.
- Comprehensive Test Discovery: Automatically finds test files and functions.
- Fixtures and Plugins: Helps with test setup and teardown.
- Powerful Assertions: Uses Python’s built-in assert statement for clear validation.
- Compatibility: Supports unit tests, functional tests, and integration tests.
Setting Up Pytest
Before diving into test writing, ensure Pytest is installed. You can install it using pip:
pip install pytest
To verify the installation, run:
pytest --version
Writing Your First Pytest Test
Let’s create a simple Python function and write a test for it.
Example Function
Create a file named calculator.py with the following function:
def add(a, b):
return a + b
Writing a Test
Now, create a test file named test_calculator.py and add the following code:
from calculator import add
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
Running the Test
Execute the test by running the following command in the terminal:
pytest
Pytest will automatically detect files and functions starting with test_ and execute them.
Using Fixtures in Pytest
Fixtures in Pytest help set up and manage test dependencies. Let’s look at an example:
import pytest
@pytest.fixture
def sample_data():
return {"name": "Alice", "age": 25}
def test_data(sample_data):
assert sample_data["name"] == "Alice"
assert sample_data["age"] == 25
Here, the sample_data function acts as a fixture and is automatically passed to test_data, reducing redundant setup code.
Running Specific Tests and Handling Failures
- Run all tests:
pytest
- Run a specific test file:
pytest test_calculator.py
- Run a specific test function:
pytest test_calculator.py::test_add
- Stop on first failure:
pytest -x
Advanced Pytest Features
Parametrized Testing
Instead of writing multiple test cases manually, Pytest allows you to use parameterized tests:
import pytest
from calculator import add
@pytest.mark.parametrize("a, b, expected", [(1, 2, 3), (5, 5, 10), (10, -5, 5)])
def test_add(a, b, expected):
assert add(a, b) == expected
This test will run three times with different values.
Skipping and Expected Failures
Sometimes, you may want to skip certain tests or mark them as expected failures:
@pytest.mark.skip(reason=”Feature under development”)
def test_unfinished_feature():
assert False
Running Only Failed Tests
To rerun only the failed tests, use:
pytest --lf
Automated testing with Pytest enhances code quality and accelerates development by catching bugs early. This guide covered the fundamentals, from installation to writing and running test cases. By leveraging fixtures and advanced features like parameterized testing, you can create more efficient and maintainable tests.



