Introduction
Part 1, Chapter 1
Writing tests is essential, but writing effective tests is challenging. Many developers struggle with tests that break on every refactor, provide false confidence with high code coverage but low actual value, or become so cumbersome to maintain that they slow down development rather than speed it up.
This course takes a practical, patterns-based approach to testing Python applications. You'll learn proven techniques that make tests resilient to refactoring, easy to write and maintain, and valuable in catching real bugs -- all while working seamlessly with AI coding tools.
What You'll Learn
By the end of this course, you'll be able to:
- Test behavior rather than implementation to make tests resistant to refactoring
- Use the factory fixtures pattern with pytest to write readable, maintainable tests
- Determine whether a test provides real value or just inflates coverage metrics
- Apply contract testing to validate I/O operations (databases, APIs, caching, blob storage)
- Use mocking effectively without creating brittle tests
- Leverage triangulation to solve problems incrementally
- Apply pytest parametrization to write tight, comprehensive test suites
- Use FastAPI dependency injection overrides to speed up test execution
- Implement snapshot testing for seamless API testing
- Apply property-based testing for data-heavy and machine learning code
- Use the humble object pattern to test hard-to-test code
- Structure code to be inherently testable
- Configure AI agents to write and maintain high-quality tests
How to Use This Course
This course is structured in two main parts:
- The first part covers core general testing techniques and patterns. Each technique includes examples and guidance on when to apply it and how it's relevant for AI-assisted development. It's a foundation for everything that's coming in the second part.
- The second part covers use-case specific techniques and how to apply them against real-world examples, like data storage and syncing to thid-party systems. Not every technique will be applicable to every project -- some are more valuable in FastAPI or non-web projects, while others are applicable everywhere. It ends with ready-to-use Claude and Cursor files that will help you steer your agents to write better tests.
The full example project is available in a GitHub repository. You can request access by contacting the email address found in the final chapter.
Tools, Frameworks, and Services
The course uses several development tools. Feel free to swap them for alternatives that better suit your needs.
pytest
pytest is a framework that makes it easy to write Python tests. It provides a simple, readable syntax and powerful features like fixtures, parametrization, and plugins.
Compared to the standard library's unittest, pytest:
- Requires less boilerplate code, making test suites more readable
- Uses the plain
assertstatement instead ofassertSomethingmethods - Updates more frequently
- Provides a sophisticated fixture system
- Has a large ecosystem of plugins
You can replace it with:
- unittest
- nose2
Poetry
Poetry is a tool for Python packaging and dependency management. It handles virtual environments, dependency resolution, and package publishing.
You can replace it with:
- uv
- pip + twine
- pipenv + twine
FastAPI
FastAPI is a modern, high-performance web framework for building APIs with Python. It provides automatic API documentation, type checking, and dependency injection out of the box.
You can replace it with:
- Flask
- Django
- Pyramid
Docker
Docker is a container platform used to streamline application development and deployment workflows across various environments. It packages application code, dependencies, and system tools into lightweight containers that can be moved from development to production quickly and easily.
✓ Mark as Completed