¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Pruebas de regresión: que un error no vuelva

Después de esta lección: Puedo convertir el informe de un error en una prueba que falla, arreglar el error y guardar la prueba.

Lección de 60 min13 comandosLaboratorio de comandos de Linux de cada día: los treinta comandos que se escriben de memoria

Un error que arreglas puede volver

Una regresión es un error que vuelve después de arreglarlo, o una función que funcionaba y deja de hacerlo tras un cambio. Una prueba de regresión es una prueba escrita para un error concreto, para que ese error no vuelva sin avisar.

En esta lección un cliente informa de un error. Tú escribes primero la prueba y después la corrección.

Al terminar esta lección

Nota

Puedo convertir el informe de un error en una prueba que falla, arreglar el error y guardar la prueba.

Palabras clave

PalabraQué significa
Regresiónun error que vuelve, o una función que deja de funcionar tras un cambio
Prueba de regresiónuna prueba escrita para un error informado, que se guarda para siempre
Informe de errorlo que dice un usuario que salió mal, con la entrada que lo causó
Rojouna ejecución en la que una prueba falla
Verdeuna ejecución en la que todas las pruebas pasan
Caso vecinouna entrada cercana a la del informe, para ver que la corrección no movió el error

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Convierte un informe en una prueba

Una tienda da una décima parte de descuento en pedidos de 100 euros o más. Un cliente escribe: "Gasté justo 100 euros y no tuve descuento."

El informe contiene la entrada: 10000 céntimos. La tienda trabaja en céntimos para que ningún precio sea una fracción. Crea primero la carpeta y el código tal como está hoy, con el defecto.

Crea una carpeta para la lección

Comando
mkdir -p ~/regtest

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Entra en ella

Comando
cd ~/regtest

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribe el código de la tienda de hoy

Comando
printf 'def discount(total_cents):\n    if total_cents > 10000:\n        return total_cents // 10\n    return 0\n' > shop.py

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribe la prueba antes de la corrección

Convierte el informe en una prueba con la entrada exacta del cliente. Ponle el nombre de lo que vio el cliente, para que un fallo se lea como el informe.

Ejecútala antes de arreglar nada. Debe fallar. Una prueba que pasa con el código roto no demuestra nada.

Escribe la prueba a partir del informe

Comando
printf 'import unittest\nfrom shop import discount\n\n\nclass DiscountReport(unittest.TestCase):\n    def test_exactly_100_euros_gets_a_tenth_off(self):\n        self.assertEqual(discount(10000), 1000)\n' > test_shop.py

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecútala y mira cómo falla

Comando
python3 -m unittest test_shop 2>&1 | grep -E "^(OK|FAILED|AssertionError)"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Arregla solo lo que muestra la prueba

El código dice > donde la regla dice "o más". Cámbialo a >= y nada más. Después ejecuta la prueba otra vez. Debe ponerse verde.

Cambia el signo mayor que

Comando
sed -i 's|total_cents > 10000|total_cents >= 10000|' shop.py

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecuta la prueba otra vez

Comando
python3 -m unittest test_shop 2>&1 | grep -E "^(OK|FAILED|AssertionError)"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Añade los vecinos del error

Una corrección puede mover un error en lugar de quitarlo. Si por error escribes >= 9999, un pedido de 99,99 euros recibe descuento. Prueba las entradas a cada lado de la del informe.

Ejemplo resuelto: los casos junto al límite

Pedido en céntimosDescuento que debe recibirPor qué está
99990Un céntimo menos: sin descuento
100001000El informe: justo en el límite
100011000Uno más: céntimos enteros, hacia abajo
250002500Muy por encima: el descuento no tiene tope

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Añade dos pruebas vecinas

Comando
printf '    def test_one_cent_under_gets_nothing(self):\n        self.assertEqual(discount(9999), 0)\n\n    def test_over_the_line_gets_a_tenth(self):\n        self.assertEqual(discount(25000), 2500)\n' >> test_shop.py

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecuta las tres

Comando
python3 -m unittest test_shop 2>&1 | grep -E "^(OK|FAILED|AssertionError)"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Demuestra que la prueba protege la corrección

Una prueba de regresión se gana su sitio cuando el error vuelve. Devuelve el error a propósito, como haría un cambio descuidado, y mira cómo lo detecta el conjunto. Después devuelve la corrección.

Devuelve el error

Comando
sed -i 's|total_cents >= 10000|total_cents > 10000|' shop.py

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecuta las pruebas

Comando
python3 -m unittest test_shop 2>&1 | grep -E "^(OK|FAILED|AssertionError)"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Devuelve la corrección

Comando
sed -i 's|total_cents > 10000|total_cents >= 10000|' shop.py

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecuta las pruebas una vez más

Comando
python3 -m unittest test_shop 2>&1 | grep -E "^(OK|FAILED|AssertionError)"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Un error frecuente

Advertencia

Mucha gente arregla el error, escribe una prueba que pasa y da el trabajo por hecho. Esa prueba nunca estuvo en rojo, así que nadie sabe si detecta el fallo. Escríbela primero, mira cómo falla y después arregla.

Más lejos: un informe sin entrada

Algunos informes no traen entrada: "el total se veía mal el martes". Antes de escribir una prueba tienes que encontrar una.

Anota tres preguntas que harías al cliente para obtener una entrada que puedas reproducir. ¿Cuál harías primero?

Sobre este laboratorio y su código: Laboratorio de comandos de Linux de cada día: los treinta comandos que se escriben de memoria

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.