Code Testing
Code testing allows you to keep your Python codebase reliable over time. Well-designed test suites catch bugs early, make refactoring safer, and give you confidence to change existing code without breaking behavior. Without tests, even small changes can have unexpected side effects, and your codebase becomes harder and riskier to evolve.
Frameworks like unittest and pytest provide rich support for organizing tests, setting up reusable fixtures, and running tests automatically.
In this context, you can follow the best practices listed below:
- Write small, focused tests. Prefer short test functions that exercise one behavior or code path at a time. Short-scoped tests are easier to reason about.
- Use fixtures to set up common test data. Put shared setup logic, such as temporary files, sample objects, or database connections, into fixtures instead of duplicating it in each test. Fixtures make test code less repetitive and more maintainable.
- Leverage parametrization in pytest to cover more cases. Use parametrization to run the same test with different inputs and expected outputs. This helps you explore edge cases and saves you from writing many independent tests with nearly identical names.
- Run tests frequently during development. Integrate tests into your daily workflow. Run them locally and in CI systems to catch and fix bugs and regressions quickly.
- Aim for reasonable test coverage. Use coverage reports to identify untested, critical paths. Don’t chase 100% coverage by adding unnecessary or low-value tests. Focus on tests that protect important behavior.
- Keep unit tests fast and deterministic. Unit tests should run quickly and produce the same result every time. Avoid randomness, real network calls, or calls to external services in your tests.
- Use mocks for external dependencies. When your code talks to databases, APIs, or other slow or unpredictable systems, replace these calls with mock objects in unit tests. This practice keeps tests focused, fast, and reliable while still allowing you to verify how your code interacts with those resources.
- Complement unit tests with integration and end-to-end tests. Use a smaller number of higher-level tests to validate complete workflows—from start to finish, exactly as a real user would experience it—as well as interactions between components in a production-like environment. This ensures that they work together seamlessly.
To see some of these ideas in practice, consider the test below.
🔴 Avoid this:
>>> def add(a, b):
... return a + b
...
>>> import random
>>> def test_add():
... a = random.randint(50, 150)
... b = random.randint(50, 150)
... result = add(a, b)
... assert 50 <= result <= 300
... print("OK")
...
>>> test_add()
OK
This test runs, but it has several issues. It uses random inputs, so failures may be intermittent and hard to reproduce. It vaguely tests the result by checking that it falls within an interval. This code also calls the test function manually and relies on print() instead of a test runner like pytest.
✅ Favor this:
import pytest
from calculations import add
@pytest.mark.parametrize(
"a, b, expected",
[
(100, 10, 110),
(100, 35, 135),
(200, -50, 150),
],
)
def test_add(a, b, expected):
assert add(a, b) == expected
In this version, the test is deterministic with explicit inputs and expected outputs. The @pytest.mark.parametrize() decorator lets you cover multiple cases with a single test function.
The assertion checks an exact result rather than a vague property, making failures easier to understand.
Related Resources
Tutorial
Effective Python Testing With pytest
In this tutorial, you'll learn how to take your testing to the next level with pytest. You'll cover intermediate and advanced pytest features such as fixtures, marks, parameters, and plugins. With pytest, you can make your test suites fast, effective, and less painful to maintain.
For additional information on related topics, take a look at the following resources:
- Python's unittest: Writing Unit Tests for Your Code (Tutorial)
- Python's doctest: Document and Test Your Code at Once (Tutorial)
- Python's assert: Debug and Test Your Code Like a Pro (Tutorial)
- Write Unit Tests for Your Python Code With ChatGPT (Tutorial)
- Understanding the Python Mock Object Library (Tutorial)
- Testing Your Code With pytest (Course)
- Effective Testing with Pytest (Quiz)
- Python's unittest: Writing Unit Tests for Your Code (Quiz)
- Using Python's assert to Debug and Test Your Code (Course)
- Improve Your Tests With the Python Mock Object Library (Course)
- Understanding the Python Mock Object Library (Quiz)