Pruebas: cambiar código sin miedo
Una prueba es una afirmación sobre tu código, escrita de forma que una máquina pueda comprobarla en un segundo. Es lo que convierte «creo que esto sigue funcionando» en «sé que esto sigue funcionando».
Son las 23:00. Tienes que cambiar cómo el carrito calcula un descuento. La función tiene cuarenta líneas, la escribió alguien que ya dejó la empresa y de ella sale el precio de todas las páginas del sitio. Cambias dos líneas y ahora tienes que averiguar si rompiste algo. Hay dos maneras de vivir: abrir el sitio, hacer clic en cada página a mano y rezar por no haberte saltado ninguna, o ejecutar un comando y tener la respuesta en dos segundos. La segunda no es magia. Son las pruebas.
Una prueba es una afirmación escrita en una forma que una máquina puede comprobar. Dices: con estas entradas, esta función debe dar esta respuesta. Luego la ejecutas. Si la respuesta coincide, la afirmación se sostuvo. Si no, acabas de aprender algo. Una prueba no demuestra que el código sea correcto: es una lista de promesas concretas, comprobadas automáticamente, cada vez.
vat(net, rate) = net * (1 + rate)
assert priceWithVat(100, 0.21) === 121
assert priceWithVat(0, 0.21) === 0
assert priceWithVat(100, 0) === 100
assert x == y
FAIL at line 6No todas las pruebas son del mismo tamaño. Una prueba unitaria coge un trozo pequeño de código —normalmente una función— y le da entradas, sin nada más de por medio: ni red, ni base de datos, ni navegador. Corre en una fracción de segundo, y cuando falla sabes exactamente qué función está rota. Una prueba de integración hace correr varios trozos reales juntos: tu código más una base de datos real, o tu código hablando por la red con otro servicio. Es más lenta, puede fallar por motivos que no tienen nada que ver con tu cambio, y detecta un tipo de error completamente distinto: el que solo aparece cuando las piezas están conectadas. Necesitas las dos, y necesitas saber cuál tienes delante.
Esta es la parte que sorprende: una prueba que falla es una buena noticia. Una prueba en rojo significa que la máquina encontró una diferencia entre lo que prometiste y lo que hace el código, y lo encontró ahora, en tu portátil, en dos segundos, en lugar del jueves que viene delante de un cliente. La versión incómoda del mismo error es la que nadie probó: llega a personas reales y te enteras por un mensaje que empieza con «oye, ¿a ti también se te ha roto la web?».
La razón real por la que los equipos escriben pruebas no tiene nada que ver con encontrar errores. Es el miedo. En un código sin pruebas cada cambio es una apuesta, así que la gente hace los cambios más pequeños posibles y evita tocar lo que funciona, incluidos esos trozos feos que piden a gritos una reescritura. Con pruebas puedes cambiar una función, ejecutar el conjunto y saber en segundos si rompiste el resto. Eso es lo que hace posible limpiar y mejorar el código. Las pruebas no son un informe para un profesor. Son lo que te deja avanzar.
Práctica
Empareja cada comprobación con lo que realmente es.
Pistas
- Pregúntate qué necesita cada comprobación para ejecutarse: ¿solo esta función o todo un sistema en marcha?
- Cuanto más lenta y realista es una comprobación, más cuesta ejecutarla y más te puede decir sobre el comportamiento real.
15 XP
Escribiste una prueba, la ejecutaste y falló. ¿Cuál es el siguiente paso más útil?
Pistas
- Pregúntate quién se equivoca cuando falla la comprobación: ¿el código o la expectativa que escribiste?
- Una prueba en rojo es información nueva. Pregúntate qué te acaba de decir, no cómo hacer que se calle.
14 XP
Ordena el proceso con el que una desarrolladora cuidadosa mata un error para siempre.
Pistas
- No puedes demostrar que un arreglo funciona hasta que has visto el error a propósito.
- La prueba antigua se queda en el conjunto para siempre: eso es lo que impide que vuelva el mismo error.
16 XP