Test-Driven Development with Python

A Comprehensive Guide to Building Robust Applications


PART I: FOUNDATIONS OF TEST-DRIVEN DEVELOPMENT

Chapter 1: Introduction to Test-Driven Development

  • What is Test-Driven Development?

  • The TDD Cycle: Red-Green-Refactor

  • Benefits and Challenges of TDD

  • TDD vs. Traditional Testing Approaches

  • When to Use TDD (and When Not To)

  • Setting Up Your Python Testing Environment

Chapter 2: Python Testing Fundamentals

Overview of Python Testing Ecosystem

unittest: Python’s Built-in Testing Framework

  • Test Cases and Test Suites

  • setUp and tearDown Methods

  • Assertions and Test Discovery

  • Test Organization and Structure

Introduction to pytest

  • Why pytest?

  • Basic Test Structure

  • Running Tests with pytest

  • pytest vs unittest: A Comparison

Your First TDD Example: Building a Calculator

Chapter 3: Advanced pytest Features

Fixtures: Setup and Teardown Done Right

  • Function, Class, Module, and Session Scopes

  • Fixture Composition and Dependencies

  • conftest.py and Fixture Sharing

Parametrized Testing

  • @pytest.mark.parametrize

  • Parametrizing Fixtures

  • Dynamic Test Generation

Markers and Custom Markers

  • Built-in Markers (skip, xfail, slow)

  • Creating Custom Markers

  • Marker-Based Test Selection

pytest Configuration

  • pytest.ini and pyproject.toml

  • Command-Line Options

  • Plugins and Extensions

Chapter 4: Test Design and Best Practices

The Test Pyramid

  • Unit Tests

  • Integration Tests

  • End-to-End Tests

  • Balancing Your Test Suite

Test Naming Conventions

The AAA Pattern (Arrange-Act-Assert)

The Given-When-Then Pattern

FIRST Principles of Testing

  • Fast, Independent, Repeatable, Self-Validating, Timely

Writing Maintainable Tests

Test Smells and Anti-Patterns

Code Coverage: Metrics and Interpretation


PART II: DERIVING AND DESIGNING TEST CASES

Chapter 5: Test Case Design Techniques

  • Equivalence Partitioning

  • Boundary Value Analysis

  • Decision Table Testing

  • State Transition Testing

  • Use Case Testing

  • Error Guessing and Experience-Based Testing

  • Combining Techniques for Comprehensive Coverage

Chapter 6: Testing Strategies for Different Scenarios

  • Testing Pure Functions

  • Testing Classes and Object-Oriented Code

  • Testing Functions with Side Effects

Testing Asynchronous Code

  • async/await Testing

  • pytest-asyncio

Additional Testing Strategies

  • Testing Exceptions and Error Handling

  • Testing Edge Cases and Corner Cases

  • Testing for Performance and Scalability

Chapter 7: Property-Based Testing with Hypothesis

  • Introduction to Property-Based Testing

  • Installing and Setting Up Hypothesis

  • Writing Property-Based Tests

  • Strategies for Test Data Generation

  • Stateful Testing

  • Shrinking: Finding Minimal Failing Cases

  • Hypothesis with pytest Integration

  • Real-World Property-Based Testing Examples


PART III: MOCKING AND TEST DOUBLES

Chapter 8: Understanding Test Doubles

Types of Test Doubles

  • Dummy Objects

  • Stubs

  • Spies

  • Mocks

  • Fakes

When to Use Each Type

The Dependency Inversion Principle

Chapter 9: Mocking with unittest.mock

The Mock Object

Creating Mocks and MagicMocks

patch, patch.object, and patch.dict

  • Decorators vs Context Managers

  • Where to Patch

Mock Specifications and Auto-Speccing

Asserting Mock Calls

  • assert_called_with

  • assert_called_once_with

  • call_args and call_args_list

Side Effects and Return Values

Mock Properties and Attributes

Chapter 10: Advanced Mocking Techniques

  • pytest-mock Plugin

  • Mocking File I/O Operations

  • Mocking Database Connections

  • Mocking HTTP Requests with responses

  • Mocking Time and Dates with freezegun

  • Mocking Environment Variables

  • Mocking External APIs

Best Practices for Mocking

  • Don’t Over-Mock

  • Mock at the Right Level

  • Verify Mock Interactions

Chapter 11: Fixtures and Test Data Management

  • Creating Test Data with Factories

  • factory_boy: Advanced Fixture Replacement

  • Faker: Generating Realistic Test Data

  • Managing Test Databases

  • Fixture Parametrization

  • Shared Fixtures and Fixture Scoping

  • Fixture Finalization and Cleanup


PART IV: TESTING PYTHON PACKAGES AND MODULES

Chapter 12: Structuring Testable Python Projects

  • Project Structure Best Practices

  • Separating Tests from Source Code

  • The src Layout vs Flat Layout

Making Your Code Testable

  • Dependency Injection

  • Interface Segregation

  • Loose Coupling

Additional Topics

  • Testing Private Methods and Internal APIs

  • Testing Module-Level Code

Chapter 13: Testing Python Packages

  • Setting Up Package Tests

  • Testing Package Installation

  • Testing Entry Points and CLI Tools

  • Testing Package Imports

  • Testing Across Python Versions with tox

  • Testing with Different Dependencies

  • nox: Flexible Test Automation

Continuous Integration for Packages

  • GitHub Actions

  • GitLab CI

  • CircleCI

  • Travis CI

Chapter 14: Code Coverage and Quality Metrics

  • Introduction to Code Coverage

  • coverage.py: Measuring Coverage

  • pytest-cov Integration

  • Branch Coverage vs Line Coverage

  • Coverage Reports and Visualization

  • Setting Coverage Thresholds

  • Mutation Testing with mutmut

  • Measuring Test Quality Beyond Coverage

Static Analysis and Linting in Tests

  • pylint

  • flake8

  • mypy for Type Checking Tests


PART V: WEB FRAMEWORK TESTING

Chapter 15: Testing Django Applications

  • Django Testing Overview

  • Django’s TestCase vs pytest-django

  • Setting Up pytest-django

Testing Django Models

  • Model Creation and Validation

  • Custom Model Methods

  • Model Managers and QuerySets

Testing Django Views

  • Function-Based Views

  • Class-Based Views

  • Testing View Responses

Testing Django Forms

  • Form Validation

  • Form Rendering

  • Custom Form Logic

Testing Django Templates

Testing Django REST Framework APIs

  • Testing Serializers

  • Testing ViewSets

  • Testing Permissions and Authentication

Additional Django Testing Topics

  • Django Test Database Management

  • Using Fixtures and Factory Boy with Django

  • Testing Django Middleware

  • Testing Django Management Commands

  • Testing Django Signals

  • Integration Testing in Django

Chapter 16: Testing Flask Applications

  • Flask Testing Overview

  • Setting Up pytest-flask

  • The Flask Test Client

  • Testing Flask Routes and Views

  • Testing Flask Blueprints

  • Testing Flask Request Context

  • Testing Flask-SQLAlchemy Models

  • Testing Flask Forms with WTForms

  • Testing Flask REST APIs

Testing Flask Extensions

  • Flask-Login

  • Flask-JWT-Extended

  • Flask-Mail

Additional Flask Testing Topics

  • Application Factories and Testing

  • Testing Flask Configuration

  • Testing Flask Error Handlers

  • Mocking in Flask Applications

Chapter 17: Testing FastAPI Applications

  • FastAPI Testing Overview

  • TestClient and HTTPX

  • Setting Up FastAPI Tests with pytest

Testing FastAPI Endpoints

  • GET, POST, PUT, DELETE Requests

  • Query Parameters and Path Parameters

  • Request Bodies and Validation

Testing Pydantic Models

Testing Dependency Injection in FastAPI

  • Testing FastAPI Middleware

  • Testing WebSocket Endpoints

  • Testing Background Tasks

Testing FastAPI Authentication

  • OAuth2 Testing

  • JWT Token Testing

Async Testing with FastAPI

Testing Database Operations

  • SQLAlchemy with FastAPI

  • Async Database Testing

Additional FastAPI Testing Topics

  • Testing File Uploads

  • Integration Testing FastAPI Applications

Chapter 18: Testing Django Ninja API

  • Introduction to Django Ninja

  • Setting Up Django Ninja Tests

  • Testing Ninja API Endpoints

  • Testing Ninja Schemas

Testing Ninja Authentication

  • API Key Authentication

  • JWT Authentication

Additional Ninja Testing Topics

  • Testing Ninja Routers

  • Testing Request/Response Models

  • Testing Ninja Pagination

  • Testing File Uploads in Ninja

  • Error Handling and Validation Testing

  • Integration with Django Testing Tools

  • Performance Testing Ninja APIs


PART VI: SPECIALIZED TESTING TECHNIQUES

Chapter 19: API Testing

  • REST API Testing Principles

  • Testing API Contracts

  • Testing API Versioning

  • Testing API Rate Limiting

  • Testing API Caching

  • Testing API Error Responses

  • Contract Testing with Pact

  • API Load Testing with Locust

  • Recording and Replaying API Calls with vcr.py

  • Testing GraphQL APIs

Chapter 20: Database Testing

  • Database Testing Strategies

  • Testing Database Migrations

  • Transaction Management in Tests

  • Using Test Databases

  • In-Memory Databases for Testing

  • Testing Raw SQL Queries

  • Testing Stored Procedures

  • Testing Database Constraints

  • Performance Testing Database Queries

  • Testing Data Integrity

Chapter 21: Testing Asynchronous Code

  • Challenges of Testing Async Code

  • pytest-asyncio Basics

  • Testing Asyncio Coroutines

  • Testing Async Context Managers

  • Testing Async Generators

  • Mocking Async Functions

  • Testing Event Loops

  • Testing Concurrent Operations

  • Testing Async Database Operations

  • Testing Async HTTP Requests

Chapter 22: Integration and End-to-End Testing

  • Integration Testing Strategies

  • Testing System Integration Points

  • Testing Third-Party API Integration

  • Docker for Integration Testing

  • Testing with Docker Compose

  • Browser Automation with Selenium

  • Modern Browser Testing with Playwright

  • Testing User Flows

  • Visual Regression Testing

  • Performance Monitoring in E2E Tests

Chapter 23: Security Testing

  • Security Testing Principles

  • Testing Authentication and Authorization

  • Testing Input Validation

  • SQL Injection Testing

  • XSS (Cross-Site Scripting) Testing

  • CSRF Protection Testing

  • Testing Password Security

  • Testing Secure Headers

  • Dependency Vulnerability Scanning

  • Static Application Security Testing (SAST)

Chapter 24: Performance and Load Testing

  • Performance Testing Principles

  • Benchmarking with pytest-benchmark

  • Profiling Test Execution

Load Testing with Locust

  • Writing Locust Tests

  • Distributed Load Testing

  • Analyzing Load Test Results

Additional Performance Testing Topics

  • Stress Testing

  • Spike Testing

  • Endurance Testing

  • Performance Regression Testing


PART VII: ADVANCED TDD PRACTICES

Chapter 25: Behavior-Driven Development (BDD)

  • Introduction to BDD

  • BDD vs TDD

  • Writing Gherkin Feature Files

pytest-bdd Framework

  • Given-When-Then Steps

  • Step Definitions

  • Scenario Outlines

Additional BDD Topics

  • behave Framework

  • Cucumber-Style Testing

  • Collaboration with Non-Technical Stakeholders

  • Living Documentation

Chapter 26: Test-Driven Development in Practice

  • TDD Workflow and Discipline

  • Starting with the Simplest Test

  • Triangulation Technique

  • Fake It Till You Make It

  • Obvious Implementation

  • Refactoring Under Test

  • Outside-In TDD (London School)

  • Inside-Out TDD (Detroit School)

  • TDD for Legacy Code

  • Test-Driven Bug Fixes

  • TDD in Team Environments

Chapter 27: Continuous Integration and Deployment

  • CI/CD Principles

  • Setting Up GitHub Actions for Testing

  • GitLab CI/CD Configuration

  • Testing in Jenkins

  • Pre-commit Hooks

  • Running Tests in Docker

  • Parallel Test Execution

  • Test Result Reporting

  • Code Coverage in CI

  • Quality Gates and Test Thresholds

  • Deployment Testing Strategies

Chapter 28: Maintaining Test Suites

  • Test Suite Performance Optimization

  • Identifying Slow Tests

  • Parallel Test Execution with pytest-xdist

  • Test Flakiness and How to Fix It

  • Refactoring Tests

  • Test Debt Management

  • Archiving Obsolete Tests

  • Test Documentation

  • Test Code Reviews

  • Measuring Test ROI


PART VIII: REAL-WORLD CASE STUDIES

Chapter 29: Case Study: Building a Blog Platform with TDD

  • Requirements and Planning

  • Setting Up the Project

  • TDD Workflow for User Authentication

  • TDD for Blog Post CRUD Operations

  • Testing Comment System

  • Testing Search Functionality

  • Testing User Permissions

  • Integration Testing

  • Deployment and Production Testing

Chapter 30: Case Study: E-Commerce API with FastAPI

  • System Architecture

  • Testing Product Catalog

  • Testing Shopping Cart Logic

  • Testing Payment Integration

  • Testing Order Processing

  • Testing Inventory Management

  • Testing User Reviews

  • Performance Testing for Black Friday

  • Security Testing

Chapter 31: Case Study: Microservices Testing

  • Microservices Architecture Overview

  • Testing Individual Services

  • Contract Testing Between Services

  • Testing Service Communication

  • Testing Event-Driven Architecture

  • Testing Service Resilience

  • End-to-End Testing Microservices

  • Monitoring and Observability


PART IX: APPENDICES

Appendix A: Testing Tools Quick Reference

  • pytest Commands and Options

  • unittest Commands and Options

  • Common pytest Plugins

  • Useful Testing Libraries

Appendix B: Testing Patterns Catalog

  • Arrange-Act-Assert Template

  • Four-Phase Test Template

  • Test Data Builders

  • Object Mother Pattern

  • Test Fixture Patterns

Appendix C: Setting Up Development Environments

  • Virtual Environments

  • Poetry for Dependency Management

  • Docker Development Environments

  • VS Code Testing Setup

  • PyCharm Testing Configuration

Appendix D: Common Testing Pitfalls

  • Testing Anti-Patterns

  • Common Mistakes in TDD

  • Mock Abuse

  • Overspecification

  • Test Interdependencies

Appendix E: Resources and Further Reading

  • Books on Testing

  • Online Courses

  • Blogs and Websites

  • Conference Talks

  • Python Testing Community


Index

About the Author