Bienvenidos sean a este post, hoy veremos teoricamente como es un test.
El Test-Driven Development tambien conocido como TDD es como lo indica el titulo un paradigma. Dado que deberia ser parte integral de cualquier proceso de desarrollo estandar. Este paradigma se utiliza para realizar tests o pruebas sobre un codigo de produccion mediante tareas automatizadas, los pasos basicos de un test son los siguientes:
- Escribe un test que falle
- Correlo para asegurarte que falla
- Escribe un codigo para poder pasarlo
- Corre el test para ver que lo pase
- Corre todo e codigo para ver si el nuevo codigo no rompe otros test
- Repetir
Algunos desarrolladores son mas de escribir los tests antes que el codigo, otros los escriben una vez finalizado el codigo y otros directamente ni los usan. Si bien existen muchisimas excusas para no escribir unit test no podemos evitar usarlos dado que las aplicaciones crecen mucho en tamaño y complejidad, cambiando sus requerimientos todo el tiempo. Tengan en cuenta que una aplicacion que posee una buena implementacion de testing es mas facil de modificar y es mas resiliente a cambio de requirimientos a futuro. Es decir, los unit test nos permiten hacer nuestro codigo mas a prueba de futuros cambios asi como estos no rompen ninguna funcionalidad existente.
Otro motivo para implementar los test es permitir que nuestra aplicacion sobreviva al paso del tiempo. Esto es asi porque en algunas ocasiones debemos crear un codigo para mejorar o solucionar errores de un codigo que tiene muchos años en produccion. A su vez, los test pueden ir desde explicar una parte del codigo hasta por que esa parte del codigo se ejecutara. Lo ideal seria correrlo en un entorno de Integracion Continua, CI por sus siglas en ingles, para que tan pronto chequeamos una porcion del codigo en control de origen, un servidor de CI extraiga la ultima version, lo genere desde cero, y corra todos los tests de forma automatica. Pero un entorno de test no sera realmente util al menos que este corriendo continuamente, tengamos un servidor de CI corriendo continuamente tests en cada check-in para asegurarnos que nuestros codigos pasen los test todo el tiempo. Hablemos sobre algunos temas relacionados a los test.
Unidad, integracion y test de aceptacion
Estos son test automatizados que pueden ser separados en tres tipos de areas o tipos de test. Tambien podemos describirlos como tests de black-box y white-box. Los de tipo white-box son aquellos donde la logica interna y la estructura son conocidos por el tester. En cambio, los black-box son aquellos donde la logica interna y estructura son desconocidos por el tester. A continuacion desarrollaremos a cada uno de estos tipos de test.
Unit test
Este tipo de test es parte de los denominados white-box. Esto es asi porque todas las interfaces externas de un bloque de codigo son eliminadas. Vamos a suponer que tenemos un bloque de codigo que realiza un llamado asincronico para cargar un bloque de un archivo JSON. Para realizar el unit test debemos omitir el JSON devuelto. Esto nos asegura que el objeto bajo test siempre maneja el mismo conjunto de datos. Otro motivo es cuando lleguen nuevos requerimientos el grupo de datos crecera y se expandira, con lo cual estos objetos bajo test deberian ser diseñados para interactuar con las interfaces y asi poder omitirlas facilmente en un escenario de testing.
Integration test
Estos son otra forma de white-box test que permite el objeto bajo test correr en un entorno cercano a como seria en un entorno de despliegue real. Continuando con el ejemplo anterior para un integration test se necesitaria llamar a los servicios REST que generan el archivo JSON y si a su vez estos servicios necesitan informacion de una base de datos, nuestro integration test necesitara informacion en la base de datos que coinicida con nuestro escenario de testing. Si consideramos a unit test como si fuera un limite alrededor del objeto en test, el integration test es una expansion a este limite para incluir objetos o servicios dependientes.
Tener integration tests automatizados te ayudaran a mejorar la calidad de tu producto. Si seguimos con el ejemplo del JSON, un error que podemos tener es que alguien modifique la estructura de nuestro archivo JSON que devuelve el servicio REST. Este seguira funcionando en nuestro test porque no llamamos a este servicio pero nuestra aplicacion fallara porque no es el archivo que esta esperando. Este tipo de errores sin un integration test se podrian ver recien en las ultimas instancias del test manual o peor aun, recien en produccion. Recuerden que mientras mas se tarde en descubrir la falla, mas dificil sera de repararlo.
Acceptance test
Estos son de tipo black-box test y por lo general son basados en escenarios. Estos podrian incorporar pantallas de usuarios multiples o interacciones del usuario para pasarlo. Por lo general, son realizados por un equipo de testing pero no quita que se pueda automatizar con las herramientas disponibles actualmente. Y automatizarlos es el verdadero santo grial del arbol de testing.
Debido a que los humanos somos propensos a cometere errores y tener un equipo que se dedique pura y exclusivamente a este tipo de test no siempre esta disponible, es caro y toma mucho tiempo. Las computadoras son mucho rapidas y eficientes que los humanos para realizar tareas repetitivas una y otra vez. Por lo tanto, tener un suite automatizado de acceptance test que corra en tiempos fuera de oficina para poder obtener un acceso temprano a los fallos de test, para reducir los inconvenientes y a su vez los costos de desarrollo. Este tipo de suite nos permite saber si la aplicacion funciona correctamente y las nuevas caracteristicas no rompieron algunas de las viejas.
Otra de las partes importantes en el testing es el unit testing framework y existen muchos para javascript. Algunos de los mas antiguos y tambien mas completos que podemos usar son:
- Jasmine (https://jasmine.github.io/)
- QUnit (https://qunitjs.com/)
- Mocho (https://mochajs.org/)
Tambien existen algunos realizados en typescript pero estos nunca terminaron de despegar. Cuando utilicemos los framework una de las cosas mas importantes que debemos tener en cuenta es el rango de caracteristicas de test que dispone. Por ejemplo, tiene la capacidad de generar errores? Puede eliminar dependencias facilmente? Nos permite un codigo de testing especial para reemplazar una llamada de la funcion completamente?
La facilidad con la cual typescript puede integrarse con librerias de javascript nos permite usar completamente unit test framework de javascript como si fuera de typescript. La mayoria de los frameworks de testing tienen una suite similar de caracteristicas, incluyendo un modo watch que detectara cambios para chequear archivos y volver a correr tests automaticamente.
En resumen, hoy hemos visto el paradigma de testeo, que es, como se compone, para que sirve, algunas de los distintos tipos de test que posee. Espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.50
