pytest · conftest · DENATRAN

Gerador de CNH em pytest

Fixture pytest com CNH válida mod-11 DENATRAN. Session fixture, conftest.py, mock de DETRAN, integração pytest-django. Ideal pra app de motorista, entregador, autoescola.

pip install fakeforge-br pytest pytest-mock

# conftest.py
import pytest
from fakeforge import FakeForge

@pytest.fixture(scope="session")
def cnhs(ff):
    return ff.cnh(100)

conftest.py

# tests/conftest.py
import pytest
from fakeforge import FakeForge

@pytest.fixture(scope="session")
def ff():
    return FakeForge()

@pytest.fixture(scope="session")
def cnhs(ff):
    return ff.cnh(100)

@pytest.fixture(scope="session")
def motoristas_completos(ff):
    """Motorista com customer + CNH correlacionado."""
    customers = ff.preset("customer", 30)
    cnhs = ff.cnh(30)
    return [
        {**c, "cnh": cnh, "categoria": "B"}
        for c, cnh in zip(customers, cnhs)
    ]

Teste validador CNH

# tests/test_validador_cnh.py
import pytest
from myapp.validators import validar_cnh

class TestValidadorCnh:
    def test_aceita_cnhs_validas_denatran(self, cnhs):
        for cnh in cnhs:
            assert validar_cnh(cnh), f"Rejeitou CNH válida: {cnh}"

    def test_rejeita_cnh_invalida(self):
        assert not validar_cnh("11111111111")
        assert not validar_cnh("12345678900")  # DV errado
        assert not validar_cnh("")

Uso em Django (pytest-django)

# tests/test_motorista_model.py
import pytest
from myapp.models import Motorista

@pytest.mark.django_db
class TestMotoristaModel:
    def test_salva_motorista_com_cnh_valida(self, motoristas_completos):
        m = motoristas_completos[0]
        obj = Motorista.objects.create(
            cpf=m["cpf"], nome=m["nome"],
            cnh=m["cnh"], categoria=m["categoria"],
        )
        assert obj.pk is not None

    def test_bulk_seed_500_motoristas(self, ff):
        customers = ff.preset("customer", 500)
        cnhs = ff.cnh(500)
        Motorista.objects.bulk_create([
            Motorista(cpf=c["cpf"], nome=c["nome"], cnh=cnh, categoria="B")
            for c, cnh in zip(customers, cnhs)
        ])
        assert Motorista.objects.count() == 500

Mock DETRAN (pytest-mock)

# tests/test_detran_check.py
class TestDetranCheck:
    @pytest.fixture(autouse=True)
    def mock_detran(self, mocker):
        return mocker.patch(
            "myapp.detran.DetranClient.consultar_cnh",
            return_value={
                "valida": True, "pontos": 0,
                "restricoes": [], "vencimento": "2028-06-15",
            }
        )

    def test_consulta_cnh_no_cadastro(self, motoristas_completos, mock_detran):
        from myapp.motorista.service import MotoristaService
        m = motoristas_completos[0]
        service = MotoristaService()

        result = service.aprovar_cadastro(cnh=m["cnh"])
        assert result["aprovado"]
        mock_detran.assert_called_once_with(m["cnh"])