PTENES
Skip to content
MODULE 5.4

🧪 Automated Testing

pytest, fixtures, mocks, coverage, and TDD with Claude Code. Tests are the safety net that lets you iterate quickly without fear of breaking things.

6
Topics
~45
Minutes
5.3
Prerequisite
Practical
Type
Progress:0%0 of 6
1

✅ pytest Basics

pytest is the standard testing framework in the Python ecosystem. A file test_*.py, functions that start with test_, e assert to check. It's that simple. Ask Claude Code: "escreve testes pytest para este modulo" and it generates tests for each function.

test_calculator.py
from calculator import add, divide

def test_add():
    assert add(2, 3) == 5
    assert add(-1, 1) == 0

def test_divide():
    assert divide(10, 2) == 5.0

def test_divide_by_zero():
    import pytest
    with pytest.raises(ZeroDivisionError):
        divide(1, 0)

# Rodar: pytest -v

In one sentence: pytest -v = instant feedback on what works and what broke.

2

🔩 Fixtures and conftest

Fixtures set up the state your tests need: a temporary database, an HTTP client, sample data. The file conftest.py shares fixtures across all test files in the directory. Use @pytest.fixture is the parameter scope to control the lifecycle.

conftest.py
import pytest
from fastapi.testclient import TestClient
from main import app

@pytest.fixture
def client():
    return TestClient(app)

@pytest.fixture
def sample_item():
    return {"name": "Widget", "price": 9.99, "tags": ["new"]}

In one sentence: fixtures = reusable setup; conftest.py = shared fixtures.

3

🎭 Mocks and Patches

Mocks simulate external dependencies. If your function calls an API, the test shouldn't depend on that API being up. Use unittest.mock.patch to replace the real call with a controlled return value. Claude Code generates precise mocks when you say what you want to isolate.

In one sentence: mock.patch = test your code without depending on the outside world.

4

📊 Coverage Report

Coverage measures which lines of your code are executed by tests. With pytest-cov, run pytest --cov=src --cov-report=html and see exactly which paths aren’t covered. Don’t aim for 100%; aim to cover the critical paths.

terminal
# Instalar
pip install pytest-cov

# Rodar com coverage
pytest --cov=src --cov-report=term-missing

# Gerar relatorio HTML
pytest --cov=src --cov-report=html
# Abrir htmlcov/index.html no browser

In one sentence: coverage shows what you DIDN'T test; focus on critical paths.

5

🔴 TDD with Claude

TDD with AI is a superpower: you write the test (the “what”), Claude Code generates the implementation (the “how”). Cycle: Red (test fails) -> Green (Claude implements until it passes) -> Refactor (Claude cleans up the code). You control the specification; AI does the heavy lifting.

TDD + Claude Code workflow

1. Write the test for the desired behavior

2. Run pytest (red: test fails)

3. Ask Claude: "implement this to pass the test"

4. Run pytest (green: test passes)

5. Ask Claude: "refactor while keeping the tests green"

In one sentence: TDD + AI = you define WHAT, Claude handles HOW.

6

🔗 CI Integration

Local tests are good; CI tests are mandatory. GitHub Actions runs pytest automatically on every push/PR. If any test fails, the merge is blocked. Claude Code generates the complete YAML workflow: "cria um GitHub Actions que roda pytest com coverage".

.github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install -r requirements.txt
      - run: pytest --cov=src -v

In one sentence: CI = tests run automatically on every push; no one breaks what works.

🧾 Module Summary

✓
pytest is the standard for Python testing.
✓
Fixtures set up state; conftest shares it.
✓
Mocks isolate external dependencies.
✓
Coverage shows what's untested.
✓
TDD + Claude = you define, AI implements.
✓
CI runs tests automatically on every push.

Next module:

5.5 — Deployment and Infrastructure: Docker, cloud, and monitoring.