¿Pirámide o cangrejo? Encuentra una estrategia de pruebas que se adapte

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 muchos fundamentos sobre cómo abordar los diferentes tipos de pruebas y lo que 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 juntos todos los tipos de pruebas que aprendiste.

Un armario con dos cajones que puedes abrir al mismo tiempo.

A continuación, aprenderás exactamente eso. En este artículo, se ofrece 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 comprender mejor su significado. Esta es una lista de estrategias con los respectivos tamaños y alcances de desarrollo.

Tamaño de la aplicación Composición del equipo Dependencia de las pruebas manuales Estrategia para las pruebas
Pequeño Solo para desarrolladores Alta Testing Ice Cone
Testing Crab
Pequeño Desarrolladores e ingenieros de QA Alta Testing Ice Cone
Testing Crab
Pequeño Solo para desarrolladores Baja Pirámide de pruebas
Grande Solo para desarrolladores Alta Trofeo de pruebas
Diamante de pruebas
Grande Desarrolladores e ingenieros de QA Alta Trofeo de pruebas
Cangrejo de pruebas
Grande Solo para desarrolladores Baja Testing Trophy
Testing Honeycomb

Analicemos con más detalle las estrategias y descubramos el significado de sus nombres.

Determina los objetivos de las pruebas: ¿Qué quieres lograr con estas pruebas?

Antes de comenzar a crear una buena estrategia, determina el objetivo de las pruebas. ¿Cuándo consideras que tu aplicación se probó lo suficiente?

Lograr una alta cobertura de pruebas suele considerarse el objetivo final de los desarrolladores cuando se trata de pruebas. Pero, ¿siempre es el mejor enfoque? Puede haber otro factor fundamental que debes tener en cuenta cuando decidas adoptar una estrategia de pruebas: satisfacer las necesidades de tus usuarios.

Como desarrollador, también usas muchas otras aplicaciones y dispositivos. En este sentido, eres el usuario que depende de que todos estos sistemas “funcionen”. A su vez, dependes de innumerables desarrolladores que hacen todo lo posible para que sus aplicaciones y dispositivos funcionen. Para revertir esta situación, como desarrollador, también te esfuerzas por cumplir con esta confianza. Por lo tanto, tu primer objetivo siempre debe ser enviar software que funcione y brindar un servicio a tus usuarios. Esto se extiende a las pruebas que escribes para garantizar la calidad de la aplicación. Kent C. Dodds lo resume muy bien en su publicación Static vs Unit vs Integration vs E2E Testing for Frontend Apps:

Cuanto más se parezcan tus pruebas a la forma en que se usa el software, más confianza te pueden dar.

por Kent C. Dodds

Kent lo describe como ganar confianza en las pruebas. Cuanto más cerca estés de los usuarios cuando elijas un tipo de prueba que se adapte, más podrás confiar en que tus pruebas tengan resultados válidos. En otras palabras, cuanto más alto subas en la pirámide, más confianza tendrás. Pero espera, ¿qué es la pirámide?

Determinación de estrategias de prueba: Cómo elegir una estrategia de prueba

Como primer paso, determina qué partes de los requisitos debes verificar para asegurarte de que se cumplan. Descubre qué tipos de pruebas usar y en qué nivel de detalle puedes obtener la mayor confianza y, al mismo tiempo, mantener una estructura de costos eficiente. Muchos desarrolladores abordan este tema con analogías. Estas son las más comunes, comenzando por la clásica.

Muchas formas, como pirámides, diamantes, conos de hielo, panales de abejas y un trofeo, que representan estrategias de prueba.

El clásico: la pirámide de pruebas

En cuanto empieces a buscar estrategias de prueba, es probable que te encuentres con la pirámide de automatización de pruebas como primera analogía. Mike Cohn presentó este concepto en su libro “Succeeding with Agile”. Más tarde, Martin Fowler amplió el concepto en su artículo Pirámide de pruebas práctica. Puedes representar la pirámide visualmente de la siguiente manera:

La pirámide de pruebas.

Como se muestra en este dibujo, la pirámide de pruebas consta de tres capas:

  1. 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 orientan a las unidades de prueba más pequeñas. Por ejemplo, consulta una prueba de unidades típica para un producto muy pequeño.

  2. Integración. Estas pruebas se encuentran en el medio de la pirámide, ya que 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.

  3. Pruebas de E2E (también llamadas pruebas de IU). Estas pruebas simulan un usuario real y su interacción. Estas pruebas necesitan más tiempo para ejecutarse y, por lo tanto, son más costosas. Se encuentran en la parte superior de la pirámide.

Confianza en comparación con recursos

Como se mencionó brevemente antes, el orden de las capas no es una coincidencia. Muestran las prioridades y los costos correspondientes. Esto te brinda una idea clara de cuántas pruebas debes escribir para cada capa. Ya lo viste en la definición de los tipos de pruebas.

Debido a que las pruebas de extremo a extremo están más cerca de tus usuarios, te brindan más confianza de que tu aplicación funciona según lo previsto. Sin embargo, requieren una pila de aplicaciones completa y un usuario simulado, por lo que también son potencialmente las más costosas. Por lo tanto, la confianza compite directamente con los recursos que necesitas para ejecutar las pruebas.

La pirámide de pruebas con flechas que muestran la dirección de la confianza y los recursos necesarios para los diferentes tipos de pruebas.

La pirámide intenta resolver este problema, ya que te permite enfocarte más en las pruebas de unidades y priorizar estrictamente los casos cubiertos por las pruebas de E2E. Por ejemplo, tus recorridos de usuario más importantes o los lugares más vulnerables a defectos. Como enfatiza Martin Fowler, los dos puntos más esenciales de la pirámide de Cohn son los siguientes:

  1. Escribe pruebas con diferentes niveles de detalle.
  2. Cuanto más alto sea el nivel, menos pruebas deberías tener.

¡La pirámide evolucionó! Adaptaciones de las pirámides de pruebas

Durante varios años, las discusiones giraron en torno a la pirámide. La pirámide parece simplificar demasiado las estrategias de prueba, deja fuera 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 perdió su forma? 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 analicémosla:

  • "Write tests". No solo porque genera confianza, sino también porque ahorra tiempo en el mantenimiento.
  • "No demasiados". La cobertura del 100% no siempre es buena porque tus pruebas no se priorizan y habrá mucho mantenimiento.
  • "Mayormente integración". Aquí, nuevamente, el énfasis está en las pruebas de integración: tienen el mayor valor comercial, ya que te brindan un nivel de confianza alto a diario y, al mismo tiempo, mantienen un tiempo de ejecución razonable.

Esto te hace volver a pensar 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 las pruebas de unidades, como se ve 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 realices una refactorización, deberás actualizar muchas de estas pruebas de unidades y es posible que te sientas tentado a omitirlas. Por lo tanto, se erosionan.

Como resultado, y junto con el mayor enfoque en las pruebas de integración, puede surgir la siguiente forma:

El rombo de prueba.

Una pirámide evoluciona a un diamante. Puedes ver las tres capas anteriores, pero con un tamaño diferente, y la capa de unidad se cortó:

  • Unidad: Escribe pruebas de unidades de la misma manera que las definiste antes. Sin embargo, debido a que tienden a erosionarse, priorizan y cubren solo los casos más críticos.
  • Integración. Las pruebas de integración que conoces, que prueban la combinación de unidades individuales.
  • E2E. Esta capa controla las pruebas de IU de manera similar a la pirámide de pruebas. Ten cuidado de escribir solo pruebas de extremo a extremo para los casos de prueba más críticos.

Prueba el panal

Hay otra adaptación, que presentó Spotify, que es similar al diamante de pruebas, pero más especializada para sistemas de software basados en microservicios. El panal de pruebas es otra analogía visual para el 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 tamaño pequeño, la complejidad más considerable de un microservicio no está dentro del servicio en sí, sino en cómo interactúa con otros. Por lo tanto, una estrategia de pruebas para un microservicio debe enfocarse principalmente en las pruebas de integración.

El panal de pruebas.

Esta forma nos recuerda a un panal de abejas, de ahí 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 aprobará o reprobará según la exactitud de otro sistema”. Estas pruebas tienen dependencias externas que debes tener en cuenta y, al contrario, tu sistema puede ser una dependencia que dañe otros sistemas. Al igual que con las pruebas de E2E en otras analogías, usa estas pruebas con cuidado, solo para los casos más esenciales.
  • Pruebas de integración. Al igual que con otras adaptaciones, debes enfocarte en esta capa. Contiene pruebas que verifican la exactitud 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 la implementación. Estas pruebas se asemejan a las pruebas 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 en la que Martin Fowler compara la pirámide de pruebas con el panal y el artículo original de Spotify.

Trofeo de pruebas

Ya puedes ver un enfoque repetitivo en las pruebas de integración. Sin embargo, otro tipo que encontraste en el artículo anterior no es la prueba en teoría, pero sigue siendo un aspecto importante que debes tener en cuenta en una estrategia de pruebas. Falta el análisis estático en la pirámide de pruebas y en la mayoría de las adaptaciones que viste hasta ahora. Hay una adaptación del trofeo de pruebas que tiene en cuenta el análisis estático y, al mismo tiempo, mantiene el enfoque en las pruebas de integración. El trofeo de pruebas se originó a partir de la cita anterior de Guillermo Rauch y fue desarrollado por Kent C. Dodds:

El trofeo de prueba.

El trofeo de pruebas 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ña un papel fundamental en esta analogía y te permite detectar errores tipográficos, de estilo y otros simplemente ejecutando los pasos de depuración que ya se describieron.
  • Pruebas de unidades. Se aseguran de que la unidad más pequeña se pruebe de forma adecuada, pero el trofeo de pruebas no las enfatizará en la misma medida que la pirámide de pruebas.
  • Integración. Este es el enfoque principal, ya que equilibra el costo y la mayor confianza de la mejor manera, como con otras adaptaciones.
  • Pruebas de IU. Incluyen pruebas visuales y de E2E, y se encuentran en la parte superior del trofeo de pruebas, similar a su rol en la pirámide de pruebas.

Para obtener más información sobre el trofeo de pruebas, consulta la entrada de blog de Kent C. Dodds sobre este tema.

Algunos enfoques más centrados en la IU

Eso está muy bien, pero no importa cómo llames a tu estrategia, ya sea "pirámide", "panal de abejas" o "diamante", aún falta algo. Si bien la automatización de pruebas es valiosa, es importante recordar que las pruebas manuales siguen siendo esenciales. Las pruebas automatizadas deben aliviar las tareas de rutina 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 debe complementarlas. ¿Existe alguna forma de integrar las pruebas manuales con la automatización para obtener resultados óptimos?

Prueba de cono de hielo y prueba de 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, por supuesto, son más costosos debido a que la ejecución de pruebas es 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 pizza de prueba.

El cono de helado de prueba.

El cono de hielo se enfoca más en las pruebas manuales o de IU y menos en las pruebas de unidades. A menudo, se forma en proyectos en los que los desarrolladores comenzaron a trabajar con solo algunas ideas sobre la estrategia de pruebas. 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 más énfasis en las pruebas visuales y de E2E:

El cangrejo de prueba.

Esta estrategia de pruebas incluye un aspecto más: verifica que tu aplicación funcione y se vea bien. El cangrejo de pruebas destaca la importancia de las pruebas visuales, que se definieron en el artículo anterior. Las pruebas de integración, divididas en pruebas de componentes y de API, pasan a un segundo plano, y las pruebas de unidades desempeñan un papel aún más secundario aquí. Puedes encontrar más detalles sobre esta estrategia de pruebas en este artículo sobre el cangrejo de pruebas.

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 cubrir menos complejidad. En este caso, una estrategia de pruebas completa que se enfoque en las pruebas de integración podría ser demasiado compleja.

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: ¡Elaboremos una estrategia!

Ahora conoces las estrategias de prueba más comunes. Empezaste con la clásica, la pirámide de pruebas, y conociste sus muchas adaptaciones. Ahora debes evaluarlos para tu producto y decidir cuál es el mejor para tu proyecto. La respuesta a esta pregunta debe comenzar con la frase favorita de todos: “Depende”. Sin embargo, eso no lo hace menos preciso.

Depende.

La elección de la estrategia de prueba más adecuada de las que se describen, e incluso de las que se omiten, depende de tu aplicación. Debe adaptarse a tu arquitectura, a tus requisitos y, por último, a tus usuarios y sus requisitos. Todo esto puede variar de una aplicación a otra. Eso es completamente normal. Recuerda que tu objetivo más importante es ayudar a tus usuarios, no una definición de libro de texto.

Por lo general, las pruebas reales son difíciles de separar y definir de forma individual. Incluso el propio Martin Fowler enfatiza el aspecto positivo de las diferentes definiciones, como en el caso de las pruebas de unidades. Como Justin Searls afirma correctamente en su tweet:

[…] escribe pruebas expresivas que establezcan límites claros, se ejecuten con rapidez y confiabilidad, y solo fallen por razones útiles.

de Justin Searls

Enfócate en las pruebas que informan errores reales que los usuarios podrían encontrar y no te distraigas de tu objetivo. Las pruebas deben diseñarse para beneficiar al usuario, no solo para proporcionar una cobertura del 100% o debatir qué porcentaje de qué tipo de prueba escribir.

Enfócate en las pruebas que informan errores reales que podrían encontrar tus usuarios y no te distraigas de tu objetivo. Las pruebas deben diseñarse para beneficiar al usuario, no solo para proporcionar una cobertura del 100% o generar debates sobre qué porcentaje de un tipo de prueba en particular debes escribir.