Sí, eso es verdad: los test son
parte del sistema y ellos participan en la arquitectura simplemente como cada
otra parte del sistema lo hace. En algunas ocasiones, esa participación es
bastante normal, en otras esta puede ser única.
Pruebas como un sistema de componentes
Hay mucha confusión con las pruebas. ¿Son parte del sistema? ¿Están fuera del sistema?
¿Cuales tipos de pruebas hay? ¿Son las pruebas unitarias y las pruebas de
integración cosas diferentes? ¿Que hay sobre los test de aceptación,
funcionales, pruebas Cucumber, TDD, BDD, prueba componentes, etc?
Este no es el objetivo de este libro entrar en ese debate y afortunadamente tampoco es
necesario. Desde un punto de vista arquitectural, todas las pruebas son lo mismo.
Ya sean pequeñas pruebas creadas por TDD, Cucumber, SpecFlow, etc. Todas son
arquitectónicamente diferentes.
Las pruebas, por su naturaleza, siguen la regla de la dependencia. Estas son muy
detalladas y concretas. Siempre depende hacía adentro el código que se está
probando. En realidad se puede pensar en las pruebas como el círculo más
externo en la arquitectura. Nada dependen de las pruebas dentro del sistema y
las pruebas siempre dependen de los componentes del sistema.
Las pruebas también son desplegables independientemente. En realidad, la mayoría del tiempo
estas se despliegan en sistemas de pruebas más que en sistemas de producción.
Así que, incluso en sistemas donde el despliegue independiente no es necesario,
las pruebas todavía estarán desplegadas independientemente.
Las pruebas son los componentes del sistema más aislados. Ellas no son necesarias para la
operación del sistema. Los usuarios no dependen de ellas. Su papel es dar
soporte al desarrollo y no a la operación. Sin embargo, no son menos
componentes del sistema que cualquier otro. De hecho, en muchos sentidos
representan el modelo que todos los demás componentes del sistema deberían seguir.
Diseño para la testabilidad
El aislamiento extremo de los test combinados con el hecho de que ellos no se
suelen desplegar, a menudo lleva a los desarrolladores a pensar que las pruebas
caen fuera del diseño del sistema. Esto es un punto de vista catastrófico. Las
pruebas que no están bien integrados en el diseño del sistema tienden a ser
frágiles y ellos hacen el sistema rígido y difícil de cambiar.
Este problema se debe al acoplamiento. Las pruebas están fuertemente acopladas al
sistema y deben cambiar con el sistema. Incluso el cambio más trivial a un
componente del sistema puede causar que se rompan muchas pruebas que estén
acopladas o requieran cambios estas pruebas.
La situación puede volverse peliaguda. Los cambios a componentes comunes del
sistema pueden causar que decenas, cientos o miles de pruebas dejen de estar en
verde. Esto se conoce como el «Fragile Tests Problem».
No es difícil ver como esto sucede. Imagina por ejemplo una batería de pruebas que
usan una GUI para verificar las reglas de negocio. Dichas pruebas pueden
empezar en la pantalla de inicio de sesión y el navegar a través de la
estructura de páginas hasta que ellos puedan verificar una regla de negocio
particular. Cualquier cambio a la página de inicio de sesión o a la estructura
de navegación puede causar que un número sustancial de pruebas se rompan.
Las pruebas frágiles a menudo tienen el perversos efecto de hacer el sistema rígido. Cuando
los desarrolladores realizan estos simples cambios al sistema se producen
fallos de pruebas de forma masiva, así que ellos se puede resistir a hacer
aquellos cambios. Por ejemplo, imagina la conversación entre el equipo de
desarrollo y el equipo de marketing que solicita un simple cambio en la
estructura de navegación que éste causara que se rompieran mil pruebas.
La solución es diseñar para poder probar el sistema. La primera regla del diseño de
software, ya sea por probar el sistema o por cualquier otro motivo, es siempre
la misma: No dependas de cosas volátiles. Las GUI son volátiles. Las baterías
de pruebas que operan el sistema a través de la GUI DEBEN ser frágiles. Por lo
tanto, diseña el sistema, y por tanto las pruebas, de manera que las reglas de
negocio se puedan verificar sin usar la GUI.
La API de pruebas
La forma de lograr este objetivo es crear una API específica que las pruebas puedan usar
para verificar todas las reglas de negocio. Esta API debería tener super
poderes que permitan a las pruebas evitar restricciones de seguridad, eviten
recursos con un alto coste (como bases de datos) y fuercen al sistema en un
estado particular verificable. Esta API será un super conjunto del conjunto de
interactores y adaptadores de interface que se usan por la interfaz de usuario.
El propósito de la API de pruebas es desacoplar las pruebas de la aplicación. Este
desacoplamiento abarca más que simplemente desadjuntar los de la UI: el
objetivo es desacoplar la estructura de pruebas de la estructura de la
aplicación.
Acoplamiento estructural
El acoplamiento estructural es uno de las más fuertes e insidiosos formas de acoplamiento
de pruebas. Imagina una batería de pruebas que tiene una clase de pruebas por
cada clase en producción y un conjunto de métodos por cada método en
producción. Tal conjunto de pruebas está profundamente acoplada a la estructura
de la aplicación.
Cuando uno cambia uno de aquellos método de producción o clases también deben cambiar un
gran número de pruebas. Consecuentemente, las pruebas son frágiles y estas
hacen el código de producción rígido.
El rol de la API de pruebas es ocultar la estructura de la aplicación de los pruebas.
Esto permite al código de producción que se pueda refactorizar y evolucionen de
maneras que no afecten a las pruebas. Esto también permite refactorizar las
pruebas y evolucionen de manera que no afecten al código de producción.
Esta separación de evolución es necesaria porque a medida que el tiempo pasa, las
pruebas tienen a convertirse más concretas y específicas. Por el contrario, el
código de producción tiende a convertirse más abstracto y general. El fuerte
acoplamiento estructural previene, o al menos impide, esta evolución necesaria
y previene el código de producción de ser tan general y flexible como
este debería.
Seguridad
Podría ser muy peligroso si los super poderes de la API de pruebas se llegaran a desplegar
en los sistemas de producción. Si esto es una preocupación, entonces la API de
prueba y las partes más peligrosas de implementación deberían mantener en un
componente separado independiente desplegable.
Conclusión
Las pruebas no están fuera del sistema. Estas son parte del sistema que debe estar bien
diseñado si ellos están para proveer los beneficios deseados de estabilidad y
regresión. Las pruebas que no están diseñadas como parte del sistema tienden a
ser frágiles y difíciles de mantener. Tales pruebas se descartan a menudo
porque son difíciles de mantener.
No hay comentarios:
Publicar un comentario