Que un programa termine sin mostrar errores no demuestra que resuelva bien su tarea. Las pruebas comparan resultados reales con resultados esperados. En esta lección prepararás casos pequeños, utilizarás aserciones y comprobarás que una corrección no rompe lo que ya funcionaba. No necesitas instalar un entorno adicional de pruebas para empezar.
Decidir antes qué debería ocurrir
Una prueba útil empieza con una expectativa concreta. «Comprobar el cálculo» es demasiado vago. «Con veintitrés fotografías y sobres de cinco deben necesitarse cinco sobres» permite comparar una salida exacta. Escribe la expectativa antes de ejecutar para evitar aceptar como correcto cualquier resultado que aparezca.
Selecciona casos de distintas clases. Para calcular cajas necesitas una cantidad que se divida exactamente, otra con resto y el caso de cero objetos. Para contar tareas pendientes necesitas una lista vacía, una lista con todas terminadas y una mezcla. La variedad importa más que repetir muchas veces el mismo tipo de entrada.
No calcules siempre la expectativa mediante la misma fórmula que estás probando. Si copias el mismo error en ambos lados la comparación puede pasar. Utiliza un razonamiento independiente: dibuja los sobres, cuenta elementos o resuelve un ejemplo a mano. Una prueba debe aportar información nueva sobre la solución.
Comprobar funciones sin interacción
Las funciones que reciben argumentos y devuelven resultados se prueban con facilidad. No tienes que escribir respuestas en una terminal ni interpretar mensajes decorativos. Copia esta función y las comprobaciones en un archivo llamado pruebas_cajas.py:
def calcular_cajas(objetos, capacidad):
return (objetos + capacidad - 1) // capacidad
assert calcular_cajas(23, 5) == 5
assert calcular_cajas(20, 5) == 4
assert calcular_cajas(0, 5) == 0
assert calcular_cajas(1, 5) == 1
print("Pruebas de cajas superadas")
assert comprueba que una expresión sea verdadera. Si no lo es lanza AssertionError. Si todas las comprobaciones pasan aparece el mensaje final. Ejecuta normalmente el archivo. Las aserciones pueden desactivarse al utilizar ciertas opciones de optimización de Python, por lo que no deben sustituir la validación de entradas de una aplicación.
Las pruebas de este ejemplo respetan el contrato de la función. No le pasan capacidad cero porque todavía no hemos definido que la función lo trate por sí misma. Si cambias el contrato para exigir una excepción ante argumentos inválidos tendrás que añadir pruebas de ese comportamiento. Primero decide la regla y después compruébala.
Ver fallar una prueba
Cambia temporalmente la fórmula por objetos // capacidad. El caso con reparto exacto seguirá dando cuatro pero veintitrés objetos producirán cuatro cajas en vez de cinco. La primera aserción debe fallar. Has demostrado que la prueba detecta precisamente el error que pretendías evitar.
Recupera la fórmula correcta y ejecuta todas las pruebas de nuevo. Esta segunda ejecución importa: no basta con arreglar el caso que acabas de ver. Una modificación puede corregir una entrada y romper otra. Volver a comprobar comportamientos anteriores se conoce como prueba de regresión.
No modifiques la expectativa solo para que la prueba pase. Si esperabas cinco y obtienes cuatro investiga cuál es correcto. Puede haber un error en el código o en la propia prueba. El criterio procede del problema que estás resolviendo, no del deseo de ver un mensaje de éxito.
Comprobar cambios de estado
Algunas funciones modifican una lista en lugar de devolver un resultado calculado. En ese caso examina el estado posterior. Para agregar una tarea puedes comprobar la longitud, el título y el estado inicial. Utiliza una lista nueva para que cada caso empiece desde una situación conocida.
def agregar_tarea(tareas, titulo):
tareas.append({"titulo": titulo, "hecha": False})
agenda = []
agregar_tarea(agenda, "Leer")
assert len(agenda) == 1
assert agenda[0]["titulo"] == "Leer"
assert agenda[0]["hecha"] is False
is False comprueba que el valor sea precisamente el booleano False. No necesitas utilizar is para comparar números o textos. En esos casos lo normal es ==. Aquí la comprobación del booleano ayuda a detectar que alguien haya guardado accidentalmente una cadena como «False».
Añade una segunda tarea y completa la primera. Comprueba que la segunda sigue pendiente. Esta prueba busca un fallo distinto del simple recuento: que dos elementos compartan por error el mismo diccionario. Una colección puede tener la longitud correcta y conservar relaciones internas incorrectas.
Pruebas manuales que siguen siendo necesarias
Las comprobaciones automáticas de funciones no evalúan por sí solas si una pregunta se entiende o si el menú vuelve a aparecer tras una entrada inválida. Para eso prepara una secuencia manual: iniciar, elegir una opción desconocida, añadir una tarea y salir. Anota exactamente qué debería verse después de cada paso.
Tampoco basta con probar únicamente piezas aisladas. Al integrar módulos pueden aparecer problemas de rutas o de orden de llamadas. Reserva una demostración completa para el proyecto final. Combina pruebas pequeñas que localizan fallos con una prueba del recorrido real que seguirá el usuario.
Errores habituales
- Comprobar solo que el programa no se detiene.
- Repetir la fórmula del programa para obtener la expectativa.
- Reutilizar datos modificados por una prueba anterior sin quererlo.
- Cambiar las expectativas para disimular un resultado incorrecto.
- Usar assert como única defensa ante entradas del usuario.
Lo que deberías recordar
- Cada prueba necesita entrada y resultado esperado.
- Los casos deben cubrir comportamientos diferentes.
- Una prueba que falla puede revelar un problema del código o de la expectativa.
- Después de una corrección debes repetir las comprobaciones anteriores.
Ejercicio práctico
Utiliza la decimotercera hoja para preparar cuatro pruebas de calcular_cajas. Escribe primero las expectativas y después las aserciones. Introduce deliberadamente la fórmula incompleta para observar el fallo. Anota qué caso lo detecta y por qué un reparto exacto no bastaba.
Recupera la versión correcta y añade las pruebas de dos tareas independientes. Conserva el archivo de comprobaciones para volver a ejecutarlo cuando cambies una función. Tu resultado será una pequeña colección de evidencias que puedes repetir, además de una explicación escrita de lo que protege cada caso.
Siguiente capítulo: Ordenar el proyecto y usar módulos.








