Treinamento de Testes Unitários Flask

As rotas Flask funcionam até pararem de funcionar, geralmente no pior momento possível. Testes unitários capturam regressões antes de chegarem à produção. O Flask tem um cliente de teste embutido que torna o teste de rotas limpo sem precisar subir um servidor real.

TL;DR: Escreva testes unitários para aplicações Flask usando o cliente de teste embutido: teste rotas, tratamento de requisições e use mocks para dependências externas.
Stack: Python, Flask, pytest, Flask test client
Nível: Intermediário
Tempo de leitura: ~20 min

Setup

pip install pytest coverage pytest-cov flask

Exemplo 1: Testes simples de funções

def get_hero_name(hero_id):
    heroes = {1: 'Iron Man', 2: 'Captain America', 3: 'Thor', 4: 'Hulk', 5: 'Black Widow'}
    return heroes.get(hero_id, 'Herói Desconhecido')

def is_avenger(hero_name):
    avengers = {'Iron Man', 'Captain America', 'Thor', 'Hulk', 'Black Widow'}
    return hero_name in avengers
from marvel import get_hero_name, is_avenger

def test_get_hero_name():
    assert get_hero_name(1) == 'Iron Man'
    assert get_hero_name(6) == 'Herói Desconhecido'

def test_is_avenger():
    assert is_avenger('Iron Man') is True
    assert is_avenger('Spider-Man') is False
pytest example1/test_marvel.py

Exemplo 2: Testes com classes e cobertura

pytest example2/test_marvel.py --cov=. --cov-report term-missing

Exemplo 3: Mockando requisições HTTP externas

from unittest.mock import patch

@patch('marvel.requests.get')
def test_fetch_hero_info(mock_get):
    mock_get.return_value.status_code = 200
    mock_get.return_value.json.return_value = {'name': 'Herói Mockado'}
    
    hero_name = Marvel.fetch_hero_info(1)
    assert hero_name == 'Herói Mockado'

Testes de integração Flask

import pytest
from app import app

@pytest.fixture
def client():
    with app.test_client() as client:
        yield client

def test_get_hero(client):
    response = client.get('/hero/1')
    data = response.get_json()
    assert response.status_code == 200
    assert data['hero_name'] == 'Iron Man'

def test_calculate_sum(client):
    response = client.post('/calculate', json={'n1': 5, 'n2': 10, 'operation': 'sum'})
    assert response.status_code == 200
    assert response.get_json()['result'] == 15

def test_operacao_invalida(client):
    response = client.post('/calculate', json={'n1': 5, 'n2': 11, 'operation': 'subtract'})
    assert response.status_code == 400

O que você construiu

Uma referência de testes Flask cobrindo testes simples de funções, testes baseados em classes, chamadas HTTP mockadas e testes de integração usando o cliente de teste Flask.

Próximos passos

  • Use app.config[“TESTING”] = True e um banco de dados separado para isolar testes dos dados de desenvolvimento.
  • Teste todos os métodos HTTP, códigos de status, corpos de resposta e casos de erro. Não teste apenas o caminho feliz.
  • Use fixtures no conftest.py para a instância do app Flask e setup do banco para que sejam compartilhados entre todos os arquivos de teste.

Dúvidas ou feedback? Me encontre no LinkedIn ou GitHub.

Deixe um comentário