Sabemos que en nuestro hilo de artículos de Cleaning the Code : "Clean Code. Cleaning the Code" y "Cleaning the Code: Nomenclatura o la importancia de llamarse Ernesto" , prometimos intercalar teoría y aplicación. Mentimos. Primero toca una buena dosis de teoría, hay que establecer unos cimientos fuertes, sobre todo cuando tratemos el tema de hoy: testing.
Antes de ponernos a refactorizar, hay algo que debemos hacer, y es plagar de tests el código que queremos limpiar. Existen ciertas técnicas de limpieza de código que no requieren una función de testing, ya que se pueden considerar “seguras”, también las iremos viendo en estos artículos, pero de momento es mejor hacernos a la idea de que vamos a tener que ponernos a testear.
Esto lo debemos hacer por dos motivos:
Y es que (y con esto hacemos la primera ampliación de qué consideramos código limpio) el código, para considerarse limpio, debe estar testeado. ¿Por qué? Porque el código limpio no debe dar miedo, y el principal beneficio de tener nuestro código lleno de tests es que estos quitan el miedo (y reducen el riesgo) de tocar cosas que funcionan, con todo lo que ello conlleva (refactorizaciones, facilidad en el desarrollo de nuevas funcionalidades, corrección de bugs, etc.).
¿Qué tipos de tests tenemos?
En el mundo testing, hay muchos tipos de tests, muchos más de los que se ven en esta pirámide, pero lo importante se puede ver en la imagen.
Primero, que los tests unitarios son la base, si no tenemos una buena suite de tests unitarios, podemos olvidarnos del resto.
Segundo, que según subimos en la pirámide, la cantidad de tests que debemos tener se reduce.
Tests unitarios
Se centran en comprobar el funcionamiento individual de cada unidad de código.
Un test unitario consta de:
Dependiendo del resultado de la aserción, se dará el test como válido o erróneo.
Características
Los test unitarios deben cumplir con las características descritas por el principio F.I.R.S.T. (Martin, 2009):
Aparte de las descritas anteriormente, otras características que deberían cumplir nuestros tests unitarios serían las siguientes:
Ventajas
Las ventajas de desarrollar tests unitarios son múltiples, por enumerar algunas de ellas:
Fomentan la refactorización del código
Si tenemos nuestro código está debidamente testado, podemos modificarlo con mayor seguridad, ya que, si cometemos algún error no contemplado, nuestros tests nos avisarán de ello.
Reducen el tiempo dedicado a la integración
Al simular las dependencias, no es necesario que otros módulos de los que dependa el nuestro estén desarrollados, basta con la interfaz de este, permitiendo el desarrollo en paralelo y simplificando la integración
Nos ayudan a entender el código
Si generamos correctamente los tests, haciéndolos autodescriptivos, pueden servir como documentación del propio código
Facilitan las pruebas y la depuración del código
Gracias a las pruebas unitarias, podemos evitar montar el entorno completo para probar o corregir una funcionalidad.
Limitaciones
Por su propia definición, los test unitarios tienen sus limitaciones, que harán que nuestro código no esté necesariamente exento de bugs, ya que como las unidades de código se prueban de forma aislada, puede que no se descubran errores como pueden ser fallos en la integración entre módulos, problemas de rendimiento, etc.
Además, no siempre se es capaz de anticipar todas las posibles entradas que puede tener un módulo.
Por lo tanto, debemos tener en cuenta que los tests unitarios deben ser complementados con otro tipo de pruebas, y mantenidos, incorporando nuevos casos de test conforme vayan siendo necesarios.
Hasta aquí por hoy
En el próximo artículo veremos un poco sobre el resto de los tipos de tests que hay y los objetivos que persiguen cada uno de ellos.