Objetivo 4: Tests

Descripción

Antes de desplegar a la infraestructura virtual, el código tiene que ser testeado, porque código que no está probado, está roto. El crear los tests unitarios y, eventualmente, una forma automática de ejecutarlos es un paso previo a llevar a cabo tareas de integración y despliegue continuo (que se verán a continuación).

Prerrequisitos

Haber pasado los tests del objetivo anterior.

Explicación

En sistemas de desarrollo ágil quien desarrolle tiene que asegurar que el código cumple todos los deseos del cliente antes de ser desplegado o simplemente incorporado a la rama principal; los tests son la implementación de esos requisitos.

Y los requisitos salen del problema original, pasando por las historias de usuario y los issues correspondientes.

Para ello se escriben una serie de tests que (eventualmente) se ejecutarán automáticamente al añadir o modificar código o cuando se solicite un pull request. Estos tests sobre el código tienen el fin obvio de asegurar la calidad del mismo, pero también en un entorno de desarrollo colaborativo permiten integrar código fácilmente asegurándose de que no se rompa nada. Si no está testeado, está roto, es el lema del desarrollador. Al ser la plasmación de las especificaciones, en cada incorporación de código la ejecución automática de los tests asegura que el código sigue cumpliendo las especificaciones.

Pero nosotros ejecutaremos los tests automáticamente sólo a partir de los siguientes objetivos.

Aunque más adelante habrá que hacer tests de todo el código que se vaya a desplegar, en este objetivo es suficiente con que se trabaje sobre la biblioteca o clase que se ha hecho en el objetivo anterior, que será la base del servicio que se vaya a escribir, y que se hagan pasar los tests para la misma, sin necesidad de escribir un programa principal o servicio que los use (lo que habrá que hacer en objetivos posteriores). Los tests son de funciones (o métodos) y unitarios, y como tales lo pasan las funciones, y lo hacen de forma independiente. De hecho, en TDD (desarrollo basado en test, Test Driven Development) se escriben los tests antes que las funciones; continuando con la gestión del proyecto iniciada en el objetivo anterior, las especificaciones y las funcionalidades tendrán que estar en un issue y este en un hito. No se cerrará ningún issue y ninguna historia de usuario sin hacer el test correspondiente que se asegure que funciona.

Evidentemente, en este objetivo es cuando hay que introducir la lógica de negocio, porque lo principal que se va a testear es esa lógica que añade valor al cliente. No hace falta que se introduzca toda la funcionalidad de la misma, pero antes de hacer cualquier despliegue hay que hacerlo, así que es mejor empezar ya; por ejemplo se puede introducir alguna lógica de validación, que va a ser previa a la lógica de negocio (e imprescindible si se usan lenguajes que no tengan un sistema de tipos adecuado). Si en el objetivo anterior sólo se han declarado objetos valor, en este tendrá que haber entidades, que son los módulos que contienen la lógica de negocio.

Elección de herramientas

Las herramientas para tests se dividen en varios niveles de abstracción, y la denominación de las mismas varía bastante con el lenguaje. Algunos lenguajes incluyen los llamados marcos o frameworks de test, que las incluyen todas; pero de forma bastante confusa, se puede llamar framework a algunas herramientas que incluyan sólo dos de estos niveles. Pero veamos cuales son, de los más bajos a los más altos.

En general, se habla de testing framework cuando incluye dos o tres de estas características. Conviene en todo caso consultar el panorama (y las mejores prácticas) en el lenguaje de nuestra elección para aclarar qué herramientas existen, qué funcionalidad precisa tienen, y finalmente elegir lo más conveniente.

Tal como se ha hecho en el objetivo anterior, hay que llevar a cabo una elección documentada de las herramientas que se van a usar. Aparte de los criterios que se quieran establecer, habrá que tener en cuenta que esta herramienta se va a usar en el objetivo siguiente, donde uno de los requisitos principales es que no se puede escribir en el directorio en el que están los fuentes, por lo que si la herramienta efectivamente escribe algún tipo de lockfile o similar, tendrá que ser configurable para que pueda escribir en un lugar donde sí haya permiso.

En general, todas las herramientas se van a seguir usando el resto del proyecto, por lo que mirar siempre hacia adelante a ver si cubren los requisitos correspondientes es conveniente.

Recursos adicionales

El material del curso cero incluye varios temas relacionados con el desarrollo basado en test. Se recomienda encarecidamente que se entiendan los conceptos.

Lista de comprobación

En este objetivo se sigue la metodología de desarrollo de todos los objetivos, como es natural. Especialmente, hay que seguir usando issues para avanzar en el código. Por eso conviene repasar la lista de comprobación de los mismos, incluida en otro objetivo.

Copia y pega en tu PR, lleva a cabo esta lista de comprobación sobre tu código, y marca todo lo que hayas hecho.

* [ ]  ¿Hay un camino claro que permita ir desde el código hasta la historia de
   usuario que desarrolla, pasando por el mensaje de commit y el issue
   correspondiente?
* [ ]  ¿Se ha intentado cubrir con tests una parte de la lógica de negocio que se
   esté desarrollando?
* [ ]  ¿Hay un producto mínimamente viable que describa lo que se va a entregar en
   este objetivo?
* [ ]  ¿En este producto mínimamente viable se han priorizado unas clases,
   módulos o paquetes más fundamentales frente a otros, movidos a otro
   PMV/Hito?
* [ ] ¿Estoy leyendo todo lo que marco o simplemente marco lo que se me pone por
delante?
* [ ] ¿Se han documentado las elecciones de biblioteca de aserciones y del
   de *test runner*?
* [ ] ¿Te has asegurado que lo que mencionas como biblioteca de aserciones y
test runners lo son realmente y tienen la misma funcionalidad? ¿O estás poniendo
`unittest` como *test runner* y `pytest` como biblioteca de aserciones?
* [ ] ¿Esa documentación incluye criterios de aceptación y también criterios de
búsqueda para las diferentes opciones?
* [ ]  ¿Se han seguido los principios F.I.R.S.T. en la creación del test y
   se ha documentado cómo se ha hecho?
* [ ]  ¿Se describe claramente en el PMV los tests que hay que pasar para que se
   considere viable?
* [ ] ¿Se han testeado también las excepciones?

Entrega de la práctica

Se recuerda al estudiante que este objetivo no consiste en “buscar framework de test para lenguage x y poner el primero que aparezca en Google”. Hay que demostrar que realmente se entiende qué es un test runner, en qué se diferencia de una biblioteca de aserciones, y que se han tomado las elecciones más adecuadas, tras establecer unos criterios antes de la elección adecuados al proyecto.

Se tendrá que haber actualizado el repositorio que se usara en los objetivos anteriores y añadir al fichero de este hito la URL del PR en el repositorio que haya correspondido, y la versión.

La descripción del proyecto tiene que seguir progresando, así que el README.md tiene que incluir una descripción real de la clase que se vaya a testear, como instalarla y testearla y qué uso va a tener dentro del servicio (o servicios) web que se van a desplegar más adelante. En un proyecto el README.md debe estar escrito para la persona que llegue, y no para que se corrija. Si hay documentación adicional, tendrá que enlazarse desde este README.md.

Habrá que añadir al fichero iv.yaml las siguientes claves:

En años anteriores, el 50% de los estudiantes que aprobó tardó una semana entre entrega y superación; el 75% necesitó algo más de dos semanas. Conviene que tratéis de organizaros para, a partir de la entrega, dedicar tiempo para que no se tarde más de este tiempo si no se quiere poner en peligro la superación del objetivo siguiente, mínimo para superar la asignatura.

Objetivos a alcanzar

  1. Aprender a elegir herramientas para llevar a cabo tests.
  2. Aprender a plasmar la lógica de negocio en código, y a testear su correcto funcionamiento mediante los tests. Este es evidentemente el subobjetivo más importante de este objetivo.
  3. Aprender a integrar las tareas como esta en la herramienta que haya de gestión de tareas.

Valoración

El alcanzar este objetivo avanzará, en principio, 15% de la puntuación de este apartado de la asignatura.