✅ 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.
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.
🔩 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.
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.
🎭 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.
📊 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.
# 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.
🔴 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.
🔗 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".
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
Next module:
5.5 — Deployment and Infrastructure: Docker, cloud, and monitoring.