Avançado 10 min de leitura 01/09/2026

Testes automatizados em Python com Pytest, do básico ao avançado

Testes automatizados com Pytest: fixtures, mocks, cobertura e integração com Django

Testar manualmente funciona até o momento em que você não lembra mais o que precisava testar. Pytest automatiza isso: você descreve o que espera, e ele avisa quando o código deixa de se comportar como prometido — antes do usuário descobrir.

Instalação e primeiro teste

pip install pytest

Crie calculadora.py:

def somar(a, b):
    return a + b

def dividir(a, b):
    if b == 0:
        raise ValueError("Divisão por zero.")
    return a / b

Crie test_calculadora.py:

from calculadora import somar, dividir
import pytest

def test_soma_positivos():
    assert somar(2, 3) == 5

def test_soma_negativos():
    assert somar(-1, -1) == -2

def test_dividir_normal():
    assert dividir(10, 2) == 5.0

def test_dividir_por_zero():
    with pytest.raises(ValueError, match="Divisão por zero"):
        dividir(10, 0)
pytest                  # roda todos os testes
pytest -v               # verbose (mostra nome de cada teste)
pytest test_calc.py     # só um arquivo

Fixtures: preparar dados reutilizáveis

Em vez de repetir a criação de objetos em cada teste, use fixtures:

import pytest
from models import Carrinho, Produto

@pytest.fixture
def carrinho_com_itens():
    c = Carrinho()
    c.adicionar(Produto("Caneta", 2.50), quantidade=3)
    c.adicionar(Produto("Caderno", 15.00), quantidade=1)
    return c

def test_total(carrinho_com_itens):
    assert carrinho_com_itens.total() == 22.50

def test_quantidade_itens(carrinho_com_itens):
    assert carrinho_com_itens.total_itens() == 4

Mocks: isolar dependências externas

Quando seu código chama uma API externa, banco ou serviço de email, você não quer que os testes dependam disso. Mocks substituem a chamada real por um valor falso controlado.

from unittest.mock import patch, MagicMock
from servicos import buscar_cotacao

def test_cotacao_dolar(mocker):
    mock_response = MagicMock()
    mock_response.json.return_value = {"USD": {"bid": "5.10"}}

    with patch("servicos.requests.get", return_value=mock_response):
        cotacao = buscar_cotacao("USD")
        assert cotacao == 5.10

Cobertura de testes

pip install pytest-cov

pytest --cov=. --cov-report=term-missing

O relatório mostra quais linhas do seu código nunca foram tocadas por nenhum teste — cada linha sem cobertura é um bug esperando para acontecer em produção.

Testando Django com pytest-django

pip install pytest-django

Crie pytest.ini na raiz do projeto:

[pytest]
DJANGO_SETTINGS_MODULE = config.settings
import pytest
from django.test import Client
from tutoriais.models import Tutorial

@pytest.mark.django_db
def test_tutorial_publicado_aparece_na_lista():
    Tutorial.objects.create(
        titulo="Teste", slug="teste", resumo="...", publicado=True
    )
    client = Client()
    response = client.get("/tutoriais/")
    assert response.status_code == 200
    assert "Teste" in response.content.decode()
O decorator @pytest.mark.django_db permite que o teste acesse o banco. O pytest-django cria um banco temporário para cada execução de testes — seus dados reais ficam intactos.

Próximos passos

Com testes no lugar, você pode refatorar com segurança. O próximo tutorial aplica isso construindo uma API REST completa com FastAPI.