Descubre cómo combinar diferentes tipos de pruebas en una estrategia razonable que coincida con tu proyecto.
¡Les damos la bienvenida nuevamente! En el último artículo, se establecieron muchas bases para abordar los diferentes tipos de pruebas y qué contienen, y se aclararon las definiciones de los tipos de pruebas. ¿Recuerdas esta pequeña imagen de meme? Es posible que te hayas preguntado cómo podrían funcionar en conjunto todos los tipos de pruebas que aprendiste.
Aprenderás exactamente eso. En este artículo, se brinda una introducción sobre cómo combinar estos tipos de pruebas en estrategias razonables y elegir una que coincida con tu proyecto.
Puedes comparar las estrategias con varias formas para captar mejor su significado. A continuación, se incluye una lista de estrategias con tamaños y alcances de desarrollo respectivos.
Analicemos con más detalle las estrategias y aprendamos el significado que hay detrás de sus nombres.
Determinar los objetivos de las pruebas: ¿qué quieres lograr con estas pruebas?
Antes de comenzar a desarrollar una buena estrategia, define tu objetivo de prueba. ¿Cuándo consideras que tu aplicación se probó lo suficiente?
Con frecuencia, lograr una alta cobertura de pruebas se considera el objetivo final de los desarrolladores cuando se trata de hacer pruebas. Pero ¿es siempre el mejor enfoque? Podría haber otro factor fundamental para considerar a la hora de elegir una estrategia de prueba: satisfacer las necesidades de tus usuarios.
Como desarrollador, también usas muchas otras aplicaciones y dispositivos. En este aspecto, eres el usuario que confía en todos estos sistemas para "funcionar". A su vez, confías en innumerables desarrolladores que harán todo lo posible para que sus aplicaciones y dispositivos funcionen. Para revertir esta situación, como desarrollador, también debes esforzarte por estar a la altura de esta confianza. Por lo tanto, tu primer objetivo siempre debería ser enviar un software que funcione y atender a tus usuarios. Esto se extiende a las pruebas que escribas para garantizar la calidad de la aplicación. Kent C. Dodds lo resume muy bien en su publicación sobre Pruebas estáticas vs. unidades vs. integración vs. E2E para apps de frontend:
Cuanto más se parezcan tus pruebas a la forma en que se usa tu software, más confianza tendrán.
por Kent C. Dodds
Kent describe esto como el aumento de confianza en las pruebas. Cuanto más te acerques a los usuarios y elijas un tipo de prueba que se adapte a tus necesidades, más podrás confiar en que tus pruebas tendrán resultados válidos. En otras palabras, cuanto más alta sea la escala de la pirámide, más confianza sentirás. Espera, ¿cuál es la pirámide?
Cómo determinar estrategias de prueba: Cómo elegir una estrategia de prueba
Como primer paso, determina qué partes de los requisitos necesitas verificar para asegurarte de que se cumplan. Descubre qué tipos de pruebas usar y en qué nivel de detalle puedes lograr el mayor nivel de confianza sin perder una estructura de costos eficiente. Muchos desarrolladores abordan este tema usando analogías. Estos son los más comunes, empezando por el clásico conocido.
La clásica: Pirámide de prueba
En cuanto comiences a buscar estrategias de prueba, probablemente te encuentres con la pirámide de automatización de pruebas como la primera analogía. Mike Cohn introdujo este concepto en su libro "Succeeding with Agile". Más adelante, Martin Fowler amplió el concepto en el artículo Pirámide de pruebas prácticas. Puedes representar la pirámide visualmente de la siguiente manera:
Como se muestra en este dibujo, la pirámide de prueba consta de tres capas:
Unidad. Estas pruebas se encuentran en la capa base de la pirámide porque son rápidas de ejecutar y fáciles de mantener. Están aislados y se dirigen a las unidades de prueba más pequeñas. Por ejemplo, consulta una prueba de unidades típica para un producto muy pequeño.
Integración. Estas pruebas están en el centro de la pirámide, porque tienen una velocidad de ejecución aceptable, pero te acercan más al usuario que las pruebas de unidades. Un ejemplo de una prueba de integración es una prueba de API. También puedes clasificar las pruebas de componentes como este tipo.
Pruebas E2E (también llamadas pruebas de IU). Estas pruebas simulan a un usuario genuino y su interacción. Estas pruebas necesitan más tiempo para ejecutarse y, por lo tanto, son más costosas. Se encuentran en la cima de la pirámide.
Confianza frente a recursos
Como se explicó brevemente anteriormente, el orden de las capas no es una coincidencia. Muestran las prioridades y los costos correspondientes. Esto te ofrece una idea clara de la cantidad de pruebas que debes escribir para cada capa. Ya viste esto en la definición de los tipos de pruebas.
Dado que las pruebas de extremo a extremo son más cercanas a los usuarios, son más seguras que las pruebas de que la aplicación funciona según lo previsto. Sin embargo, requieren una pila de aplicaciones completa y un usuario simulado, por lo que posiblemente también sean los más costosos. Por lo tanto, la confianza está en la competencia directa con los recursos que se necesitan para ejecutar las pruebas.
La pirámide intenta resolver este problema haciendo que te enfoques más en las pruebas de unidades y priorice estrictamente los casos cubiertos por las pruebas E2E. Por ejemplo, los recorridos de usuario más importantes o los lugares más vulnerables a los defectos. Como enfatiza Martin Fowler, los dos puntos más esenciales de la pirámide de Cohn son los siguientes:
- Escribe pruebas con un nivel de detalle diferente.
- Cuanto más alto nivel obtengas, menos pruebas deberías tener.
La pirámide evolucionó. Adaptaciones de las pirámides de prueba
Durante varios años, las discusiones han girado en torno a la pirámide. La pirámide parece simplificar en exceso las estrategias de prueba, omite muchos tipos de pruebas y ya no se ajusta a todos los proyectos del mundo real. Por lo tanto, puede ser engañoso. ¿La pirámide se desmoronó? Guillermo Rauch tiene una opinión al respecto:
Escribe pruebas. Son pocas. Mayormente integración.
por Guillermo Rauch
Es una de las citas más citadas sobre este tema, así que vamos a desglosarlo:
- “Escribe pruebas”. No solo porque genera confianza, sino también porque ahorra tiempo en mantenimiento.
- "No hay demasiados". La cobertura del 100% no siempre es buena porque las pruebas no tienen prioridad y habrá mucho mantenimiento.
- “Mayor integración”. Aquí, una vez más, el énfasis está en las pruebas de integración: tienen el mayor valor comercial, ya que te ofrecen un alto nivel de confianza diario y, al mismo tiempo, mantienen un tiempo de ejecución razonable.
Esto te hace pensar de nuevo en la pirámide de pruebas y cambiar tu enfoque a las pruebas de integración. En los últimos años, se propusieron muchas adaptaciones, así que veamos las más comunes.
Diamante de prueba
La primera adaptación quita el énfasis excesivo en la prueba de unidades, como se observa en la pirámide de pruebas. Imagina que alcanzaste el 100% de cobertura en las pruebas de unidades. Sin embargo, la próxima vez que refactorices, tendrás que actualizar muchas de estas pruebas de unidades y puedes verte tentado a omitirlas. Entonces, se erosionan.
Como resultado, junto con el mayor enfoque en las pruebas de integración, es posible que surja la siguiente forma:
Una pirámide se convierte en un diamante. Puedes ver las tres capas anteriores, pero con un tamaño diferente, y se cortó la capa de la unidad:
- Unidad. Escribe pruebas de unidades de la forma en que las definiste antes. Sin embargo, debido a que tienden a erosionar, priorizar y abarcar solo los casos más críticos.
- Integración. Las pruebas de integración que conoces, que evalúan la combinación de unidades individuales.
- E2E Esta capa controla las pruebas de IU de manera similar a la pirámide de pruebas. Asegúrate de escribir pruebas E2E únicamente para los casos de prueba más importantes.
Probando un panal
Spotify introdujo otra adaptación que es similar al diamante de prueba, pero especializada aún más para sistemas de software basados en microservicios. El panal de pruebas es otra analogía visual del nivel de detalle, el alcance y la cantidad de pruebas que se deben escribir para un sistema de software basado en microservicios. Debido a su pequeño tamaño, la complejidad más considerable en un microservicio no se encuentra dentro del servicio, sino en la forma en que interactúa con otros. Por lo tanto, una estrategia de prueba para un microservicio debe enfocarse principalmente en las pruebas de integración.
Esta forma nos recuerda a un panal; así es el nombre. Tiene las siguientes capas:
- Pruebas integradas. El artículo de Spotify usa una cita de J. B. Rainsberger para definir esta capa: "Una prueba que se aprobará o fracasará en función de la precisión de otro sistema". Esas pruebas tienen dependencias externas que debes tener en cuenta y, por el contrario, tu sistema podría ser una dependencia que rompe otros sistemas. Al igual que las pruebas E2E en otras analogías, úsalas con cuidado, solo para los casos más esenciales.
- Pruebas de integración. Al igual que en otras adaptaciones, debes enfocarte en esta capa. Contiene pruebas que verifican la precisión de tu servicio de forma más aislada, pero en combinación con otros servicios. Esto significa que las pruebas también incluirán otros sistemas y se enfocarán en los puntos de interacción, por ejemplo, a través de pruebas de API.
- Pruebas sobre los detalles de implementación. Estas pruebas se asemejan a las de unidades, que se enfocan en partes del código que están aisladas de forma natural y, por lo tanto, tienen su propia complejidad interna.
Si quieres obtener más información sobre esta estrategia de pruebas, consulta la publicación que compara la pirámide de pruebas con el panal de Martin Fowler y el artículo original de Spotify.
Trofeo de prueba
Ya puedes ver un enfoque recurrente en las pruebas de integración. Sin embargo, otro tipo con el que te encontraste en el artículo anterior no es la prueba en teoría, pero sigue siendo un aspecto importante que debes considerar en una estrategia de prueba. Falta el análisis estático en la pirámide de prueba y en la mayoría de las adaptaciones que viste hasta ahora. La adaptación del trofeo de prueba tiene en cuenta el análisis estático y, al mismo tiempo, mantiene el enfoque en las pruebas de integración. El trofeo de prueba se originó a partir de una cita anterior de Guillermo Rauch y fue desarrollado por Kent C. Puntos débiles:
El trofeo de prueba es una analogía que representa el nivel de detalle de las pruebas de una manera ligeramente diferente. Tiene cuatro capas:
- Análisis estático. Desempeñan un papel fundamental en esta analogía y te permiten detectar errores tipográficos, de estilo y otros errores simplemente ejecutando los pasos de depuración ya descritos.
- Pruebas de unidades. Si bien se aseguran de que la unidad más pequeña se pruebe de forma adecuada, el trofeo de prueba no los enfatizará en el mismo grado que la pirámide de prueba.
- Integración. Este es el enfoque principal, ya que equilibra el costo y el aumento de confianza de la mejor manera, como con otras adaptaciones.
- Pruebas de la IU. Incluyendo pruebas visuales y de extremo a extremo, están en la cima del trofeo de prueba, de manera similar a su papel en la pirámide de pruebas.
Para obtener más información sobre el trofeo de prueba, consulta la entrada de blog de Kent C. Dodds sobre este tema.
Otros enfoques centrados en la IU
Está muy bien, pero independientemente de cómo llames a tu estrategia "pirámide", "panal de miel" o "diamante", todavía falta algo. Si bien la automatización de pruebas es valiosa, es importante recordar que las pruebas manuales siguen siendo esenciales. Las pruebas automatizadas deberían aliviar las tareas rutinarias y liberar a los ingenieros de control de calidad para que se enfoquen en áreas cruciales. En lugar de reemplazar las pruebas manuales, la automatización debería complementarla. ¿Existe alguna forma de integrar las pruebas manuales con la automatización para obtener resultados óptimos?
Probando un cono de hielo y probando un cangrejo
De hecho, hay dos adaptaciones de la pirámide de pruebas que se enfocan más en estas formas de prueba centradas en la IU. Ambos tienen la ventaja de una alta confianza, pero son naturalmente más costosos debido a una ejecución de prueba más lenta.
El primero, el cono de hielo de prueba, se parece a la pirámide invertida. Sin el paso de prueba manual, también se conoce como la pizza de prueba.
El cono de hielo tiene mayor enfoque en las pruebas manuales o de IU y el menor enfoque en la prueba de unidades. A menudo toma forma en proyectos en los que los desarrolladores comenzaron a trabajar con solo algunas ideas sobre la estrategia de prueba. El código de hielo se considera un antipatrón y, con razón, es costoso en términos de recursos y trabajo manual.
El cangrejo de prueba es similar al cono de hielo de prueba, pero con mayor énfasis en las pruebas E2E y visuales:
Esta estrategia de prueba incluye un aspecto más: verifica que tu aplicación funcione y se vea bien. El cangrejo de prueba destaca la importancia de las pruebas visuales, que se definen en el artículo anterior. Las pruebas de integración, divididas en pruebas de componentes y API, pasan a un segundo plano, y la prueba de unidades desempeña un papel aún más secundario. Puedes encontrar más detalles sobre esta estrategia de prueba en este artículo sobre el cangrejo de prueba.
Si bien son más costosas, estas dos estrategias de prueba tienen su lugar: por ejemplo, en proyectos más pequeños en los que se necesitan menos pruebas o se debe abarcar menos complejidad. En este caso, una estrategia de prueba completa centrada en las pruebas de integración podría estar sobre ingeniería.
Aunque estas dos estrategias de prueba son más costosas, tienen su lugar, por ejemplo, en proyectos más pequeños que requieren menos pruebas y no necesitan cubrir mucha complejidad. En este caso, una estrategia de pruebas a gran escala centrada en las pruebas de integración puede ser innecesariamente compleja.
Consejo práctico: ¡elaboramos estrategias!
Ahora conoces las estrategias de prueba más comunes. Comenzaste con la clásica, la pirámide de prueba, y conociste sus numerosas adaptaciones. Ahora debes evaluarlas en función de tu producto y decidir cuál es la mejor para tu proyecto. La respuesta a esta pregunta debe comenzar con el elemento favorito de todos, "Depende". Sin embargo, eso no lo hace menos preciso.
La elección de la estrategia de prueba más adecuada de las descritas (incluso las excluidas) depende de tu aplicación. Debe estar a la altura de tu arquitectura, tus requisitos y, por último, los usuarios y sus requisitos. Todo esto puede variar de una aplicación a otra. Es completamente normal. Recuerda que tu objetivo más importante es servir a tus usuarios, no una definición de libro de texto.
La mayoría de las veces, las pruebas del mundo real son difíciles de separar y definir de forma individual. Incluso el propio Martin Fowler enfatiza el aspecto positivo de las definiciones diferentes, como en el caso de las pruebas de unidades. Como lo indica correctamente Justin Searls en su tweet:
[...] escribir pruebas expresivas que establezcan límites claros, se ejecuten con rapidez y confiabilidad y solo fallen por razones útiles.
de Justin Searls
Concéntrate en las pruebas que informan errores reales que los usuarios podrían encontrar y no te distraigas de tu objetivo. Las pruebas deben estar diseñadas para beneficiar al usuario, no solo para proporcionar una cobertura del 100% o para debatir qué porcentaje de qué tipo de prueba escribir.
Concéntrate en las pruebas que informen errores de la vida real que los usuarios podrían encontrar y que no se distraigan de tu objetivo. Las pruebas deben estar diseñadas para beneficiar al usuario, no solo proporcionar una cobertura del 100% o suscitar debates sobre qué porcentaje de un tipo de prueba particular deberías escribir.