pytest sobre los servicios de TicketFlow. Sin solutions.md hasta entregar.
Ejercicio 1 — La auditoría de la suite
- Corre
pytest --durations=10(omanage.py test): lista los 10 test más lentos. Clasifica cada uno: unitaria legítima / integración disfrazada / test del tiempo real. - Caza los anti-patrones en TU suite: un test que depende de otro (corre el archivo completo vs test a test), un assertion de mensaje literal, un
sleep, un mock de ORM. Documenta cada hallazgo con el nombre del test. - Migra 3 tests de la suite vieja (
manage.py test→ pytest): el setUp → fixture, y uno de ellos parametrizado. Verifica que la suite entera sigue en verde con ambos runners.
Ejercicio 2 — La parametrización que sobrevive
- Escribe
test_calcular_totalcon 6 casos parametrizados (1 asiento, 3, 10, 0 [error], -1 [error], 1000 [límite]) — tabla de casos arriba, assertion única abajo. - El test debe sobrevivir a DOS refactors: renombra
calcular_total→precio_pory cambia su firma interna (extrae_descuento_volumen). Los tests NO se editan. ¿Cuántos murieron? (esperado: 0 si probabas el QUÉ). - Añade el caso de la comisión del org (la 08) con
parametrizesobrepytest.param(..., id="org-10-pct")— los ids legibles en el reporte.
Ejercicio 3 — Fakes antes que mocks
- Escribe el fixture
gateway_rechaza(FakeGateway configurable:declina_todo,timeout_pero_cobra— el de la 32) y reescribe 3 tests que maqueaban la pasarela conpatch. ¿Cuántas líneas se ahorraron y qué assertion nueva te permitió (el estado de la saga)? - El test del repositorio: reescribe el test de reserva duplicada (10) con
InMemoryReservationRepository(25) SIN BD. ¿En cuántos ms corre? (midelo con--durations). - El único mock legítimo: verifica que
enviar_email_confirmacion.delayse ENCOLA vía on_commit (la interacción ES el contrato aquí). Escribe el test concaptureOnCommitCallbacksy el mock de la tarea.
Ejercicio 4 — Los test del CÓMO, cazados
- Escribe un test MALO a propósito:
with patch("reservations.services.Seat.objects") as mock_seat:... mock_seat.filter.assert_called_once(). Ahora refactorizareservar()(usaselect_for_updateen vez defilter): el test bueno sigue verde, el malo muere. Pega la evidencia de ambos. - El mensaje literal: encuentra un test con assertion de texto completo y cámbialo a
err.code. Verifica: cambia el texto del error humano → test verde.
Ejercicio 5 — La convención del proyecto
- Escribe el
conftest.pydel proyecto con las 5 fixtures base (clock_fijo, evento, comprador, gateway, mailbox) y documenta cada una con docstring de una línea. - Renombra 5 tests a la convención
test_<sujeto>_<escenario>_<resultado>y corre la suite:pytest -k "reservar"debe encontrarlos todos por keyword. - Mide la cobertura de
services/:pytest --cov=reservations.services --cov-report=term. ¿Qué servicio está por debajo del 90% y qué línea NO está probada? (la respuesta no es "añade test": es "¿esa línea es código muerto?").
Entrega
Pega el reporte de durations, los 3 tests migrados, el antes/después de los mocks→fakes y la cobertura de servicios. Después: Lección 34 — Pruebas de integración.