Saltar al contenido

Aprenda los fundamentos del desarrollo basado en pruebas en JavaScript

En resumen, TDD cambia nuestro flujo de trabajo habitual. Tradicionalmente, el flujo de trabajo de desarrollo de software es sobre todo un bucle de los siguientes pasos:

  1. Piensa en lo que se supone que hace tu código.
  2. Escriba el código para hacerlo.
  3. Pruebe el código para ver si funciona.

Por ejemplo, digamos que queremos escribir una función sumar (número1, número2) para sumar dos números. Primero, escribimos la función de sumar, luego probamos algunos ejemplos para ver si da el resultado que esperamos. Podríamos intentar ejecutar add(1,1), add(5,7) y add(-4, 5), y podríamos obtener las salidas 2, 12, y… oops, debe haber un error en algún lugar, -9.

Aprenda los fundamentos del desarrollo basado en pruebas en JavaScript
Aprenda los fundamentos del desarrollo basado en pruebas en JavaScript

Revisamos el código para intentar arreglar la salida incorrecta, y luego ejecutamos add(-4, 5) de nuevo. Tal vez devuelva 1, tal como queríamos. Sólo para estar seguros, ejecutaremos los otros ejemplos para ver si todavía dan la salida correcta. Oops, ahora add(5,7) devuelve -2. Pasaremos por algunos ciclos de esto: revisaremos nuestro código y luego probaremos algunos ejemplos hasta que estemos suficientemente seguros de que nuestro código funciona tal como queremos.

El desarrollo dirigido por pruebas cambia este flujo de trabajo escribiendo pruebas automatizadas, y escribiendo pruebas antes de que escribamos el código. Aquí está nuestro nuevo flujo de trabajo:

  1. Piensa en lo que se supone que hace tu código.
  2. Escriba pruebas que especifiquen lo que espera que haga su código.
  3. Escriba el código para hacerlo.
  4. Mira si el código funciona comparándolo con las pruebas que escribiste.

Así que, antes de empezar a escribir nuestra función de adición, escribiremos algún código de prueba que especifique qué salida esperamos. Esto se llama prueba de unidad . Las pruebas unitarias pueden tener un aspecto parecido a esto:

123expect(add(1,1)).toEqual(2);expect(add(5,7)).toEqual(12);expect(add(-4,5)).toEqual(1);

javascript

Podemos hacer esto por tantos ejemplos de prueba como queramos. Luego, escribiremos la función de agregar. Cuando hayamos terminado, podemos ejecutar el código de prueba y nos dirá si nuestra función pasa todas las pruebas:

OK, entonces fallamos una de las pruebas. Revisaremos el código para tratar de corregir el error, y luego haremos las pruebas de nuevo:

Oops, arreglamos una cosa pero rompimos otras al mismo tiempo. Revisaremos el código de nuevo y veremos si todavía hay algún problema:

Por supuesto, sólo porque nuestro código haya pasado las pruebas no significa que el código funcione en general. Pero nos da un poco más de confianza sobre su corrección. Y si en el futuro encontramos un error que nuestras pruebas no hayan superado, siempre podemos añadir más pruebas para una mejor cobertura.

Muchos de ustedes podrían objetar, » ¿Pero cuál es el punto de eso? ¿No es sólo un montón de molestias extras sin sentido? «

Es cierto que establecer el entorno de prueba y averiguar cómo se realizan las pruebas de escritura de la unidad a menudo requiere cierto esfuerzo. A corto plazo, es más rápido hacer las cosas de la manera tradicional. Pero a largo plazo, el TDD puede ahorrar tiempo que de otra manera se perdería al probar manualmente la misma cosa repetidamente. Y sucede que hay un número de otros beneficios en las pruebas de unidad:

Detección automática de regresión

A veces escribes un error en tu programa que hace que el código que antes funcionaba correctamente ya no lo haga, o vuelves a introducir accidentalmente un viejo error que ya habías arreglado. Esto se llama una regresión . Las regresiones pueden pasar desapercibidas durante mucho tiempo si no tienes ninguna prueba automatizada. Pasar las pruebas de unidad no garantiza que tu código funcione correctamente, pero si escribes pruebas para cada error que arregles, una cosa que pasa las pruebas de unidad puede garantizar es que no has reintroducido un error antiguo.

Refactorización audaz

El código puede desordenarse muy rápidamente, pero a menudo da miedo refactorizarlo ya que hay una buena posibilidad de que se rompa algo en el proceso. Después de todo, el código a menudo se ve desordenado porque tuviste que hackear algunas soluciones para que funcionara en casos poco comunes. Cuando intentas limpiarlo, o incluso reescribirlo desde cero, es probable que falle en esos casos de borde. Si tienes pruebas de unidad que cubran estas cajas de borde, descubrirás inmediatamente cuando hayas roto algo y podrás hacer cambios con más valentía.

Documentación

Si otro desarrollador (o quizás el futuro tú) no puede averiguar cómo usar el código que has escrito, pueden mirar las pruebas de unidad para ver cómo se diseñó el código para ser usado. Las pruebas unitarias no son un sustituto de la documentación real, por supuesto, pero son ciertamente mejores que la ausencia de documentación (lo cual es muy común, ya que los programadores casi siempre tienen las cosas más arriba en sus listas de prioridades que la documentación escrita).

Robustez

Cuando no hay pruebas automatizadas y las aplicaciones se vuelven suficientemente complejas, es fácil que el código se sienta muy frágil. Es decir, parece funcionar bien (la mayoría de las veces) cuando lo usas, pero tienes una ansiedad persistente de que la más mínima acción inesperada del usuario o la más mínima modificación futura del código hará que todo se caiga y se queme. Saber que su código pasa una serie de pruebas de unidad es más tranquilizador que saber que su código parecía funcionar cuando lo probó manualmente con un puñado de ejemplos el otro día.

Bien, basta de teoría, ensuciémonos las manos y veamos cómo funciona esto en la práctica.