Testar FastAPI Sem Mocks da BD
Não mocks o teu banco de dados nos testes.

Não mocks o teu banco de dados nos testes.
O projecto FastAPI de referência que mantenho tem 71 testes a 100% de cobertura a correr em menos de um segundo — a tocar numa sessão SQLAlchemy real, sem subir servidor, sem docker-compose, sem fingir SQL.
O setup que faz isto funcionar:
1. SQLite em memória + `StaticPool`. Uma única base partilhada para toda a sessão de testes. `connect_args={"check_same_thread": False}` permite que várias sessões async lhe toquem.
2. `pytest-asyncio` em modo `auto`. Cada `async def test_...` corre como coroutine sem precisar do decorator `@pytest.mark.asyncio` em cada teste.
3. `AsyncClient` sobre `ASGITransport`. Sem socket, sem TCP, sem serialização de bytes. `transport = ASGITransport(app=app)` e chamas os teus handlers directamente em memória. Cada request é uma coroutine.
4. `app.dependency_overrides[get_session] = override_session`. Troca a factory de sessão de prod pela versão SQLite na camada de DI do FastAPI. Restaurada com `app.dependency_overrides.clear()` no teardown.
5. Reset de schema por teste. Uma fixture trunca a tabela `books` entre testes para cada um começar com a tabela vazia. O schema é criado uma vez no início da sessão e largado no fim.
6. Parametriza os branches chatos. `@pytest.mark.parametrize("field", ["title", "author", "isbn"])` cobre três caminhos idênticos de validação com uma só definição de teste.
Porque mockar o banco é a resposta errada:
— Mocks ensinam o teu teste sobre o teu código, não sobre o teu banco. Em produção, vais ter `IntegrityError` em chave duplicada; o teu mock não, porque ninguém escreveu esse branch.
— Mocks apodrecem. O comportamento mockado deixa de bater com o SQLAlchemy à medida que a lib evolui. Testes reais falham quando a realidade muda; testes mockados passam errados.
— SQLite é rápido o suficiente. 71 testes herméticos contra um schema real correm em menos de um segundo. O argumento do custo morreu.
— A única limitação: SQL específico do dialecto. Se usas `JSONB` ou funções só-Postgres, adiciona uma camada de integração por cima da hermética. A maioria das apps não precisa.
O que é uma cobertura de testes a sério:
um teste por branch de cada rota (422, 415, 409, 404, 500), cada operação do repository incluindo as bordas de erro, alguns testes de schema a fixar o contrato, e `--cov-fail-under=100` no CI. Se não consegues chegar a 100 num projecto pequeno, tens código morto.
Qual é a suite de testes mais lenta que considerarias aceitável para uma API CRUD — e porquê?
P.S. Código: https://github.com/bilouro/FastAPIProject
P.S. Novo post tech toda a quarta-feira.
#FastAPI #Pytest #TestesDeSoftware