Los tests son importantes, ya hemos dado la turra en el blog bastantes veces: desde cómo organizar los test, estrategias para escribir mejores tests, o incluso hemos hablado «la jerga del testing», pero un tema que siempre hemos dado por sentado es la pirámide de test.
La pirámide de test o pirámide de Cohn, es un framework que propone la agrupación de dichas pruebas en capas y la cantidad relativa que se debe crear por cada capa: Unitarias, Servicio, UI. La pregunta es ¿de verdad una pirámide siempre es la mejor solución? Pues la respuesta como siempre es depende.
Leer más: ¿La piramide del testing?Introducción
Todos sabemos que realizar tests en nuestro proyecto software nos aporta confianza para que podamos realizar cambios en el mismo. Además dichos test tienen que cumplir una serie de características como:
- Independiente: el test debe devolver el mismo resultado independientemente de cuando se ejecute
- Determinista: si nada ha cambiado, el resultado debe seguir siendo el mismo
- Pequeño: como el dicho, «el que mucho abarca poco aprieta»
- Legible: debe estar escrito en un lenguaje claro y fácil de entender.
- Repetible: debe poder ejecutarse varias veces
- Propósito: deber ser preciso, y debe testear algo exacto.
También conocemos que tenemos distintos tipos de tests:
- Test unitarios: Una prueba (pieza de código) automatizada, simple, repetible y mantenida que invoca una unidad de trabajo en el sistema y luego verifica una sola suposición sobre el comportamiento de esa unidad de trabajo
- Test de integración: valida dos o más módulos de software dependientes (o componentes) como un grupo de múltiples maneras.
- Test de UI: son realizadas a través de la interfaz de usuario para probar componentes juntos en escenarios. Estas pruebas generalmente conducen su aplicación a través de su interfaz de usuario (UI) e incluyen pruebas funcionales de los controles de la UI.
- Test de aceptación: Una prueba de aceptación manual valida si se cumple un requisito o especificación.
¿Cómo combinamos todo estos tipos de test cuando trabajamos en nuestro proyecto? La respuesta la tendremos en los modelos de testing.
Modelos de testing
Ya hemos hablado de que hacer test nos ayuda a producir software de más calidad y a reducir el tiempo de cambios, pero elegir la estrategia que queremos seguir a la hora de hacer testing es algo que dependerá del contexto. El objetivo es tener una imagen mental sobre la cantidad de esfuerzo que debemos dedicar a cada tipo de test y en particular al equilibrio entre los unitarios y las demás.
Los modelos de testing sirven como base para poder hablar y decidir que tipos de pruebas tenemos y necesitamos en nuestro sistema, que velocidad tiene nuestro pipeline de integración continua, cuanto tiempo es necesario para poder desplegar una nueva versión de nuestro código,… cual es la naturaleza de nuestro proyecto.
Ahora presentamos algunos modelos de testing que podríamos tener en cuenta a la hora de invertir esfuerzo en el testing dentro de nuestro proyecto.
Piramide de testing
Seguro que ya hemos visto o hemos escuchado hablar de esta pirámide de la imagen anteriormente. La pirámide intenta representar visualmente una organización lógica de los distintos tipos de pruebas. La pirámide nos indica que la mayoría de los tests deberíamos realizarlos como test unitarios, tener luego una capa de test de servicio y finalmente unos pocos test de UI.
- test unitarios no dependen de recursos externos, es decir, no se conectan a la base de datos, ni a ficheros ni usan recursos api externas, prueban una unidad, que bien podría ser una clase o más de una dependiendo del concepto que tengamos de unidad.
- test servicio o funcionales o de integración son los que prueban una funcionalidad, o de servicio que necesita diferentes módulos de software que están integrados lógicamente y se prueban como un grupo. Estos test pueden acceder a la base de datos y a sistemas que estén bajo nuestro control (Redis, apis del propio sistema,…) pero en el caso que haya sistemas externos que no estén bajo nuestro control utilizaríamos dobles de pruebas (por ejemplo, llamar a la API de Google o Facebook).
- test de UI, o de aceptación verificamos la aplicación desde la interfaz de usuario, ya sea llamando a un endpoint de una API o simulando clicar en botones.
Diamante de pruebas o Trofeo de pruebas
Con el diamante tenemos los mismos tipos de test pero la proporción cambia entre las diferentes formas.

La parte de static son test más pensados para javascript o lenguajes dinámicos, ya que nos ayudan cazar typos y errores, en PHP ya con las nuevas versiones tenemos tipos por lo que no son tan necesarios estos test.
Esta modelo de testing se suele utilizar en proyectos heredados/legacy, donde realizar pruebas unitarias puede ser complicado, pero es una necesidad fundamental. O también podríamos si estamos trabajando con dispositivos físicos o incluso si nuestro proyecto tiene que interactuar con otros sistemas/apis,… Por ello, optamos por hacer más test de integración aunque eso suponga que la batería de test tarde más tiempo en ejecutarse. Al final lo que se trata es de tener un arnés de seguridad que nos genere confianza a la hora de trabajar en el proyecto.
El hecho de tener una base de test estáticos quizás no tenga sentido en algunos lenguajes de tipado fuerte o en versiones nuevas de PHP, pero puede ayudarnos en algunas situaciones.
Pirámide invertida o cono de helado
Esta forma podemos encontrarla cuando la mayoría de los test se centran en pruebas end-to-end y donde hay un componente grande de testing manual.

A simple vista, podría ser un antipatrón, donde hay una gran capa de test manuales y en cierto sentido lo es, ya que a medida de que el proyecto crezca la cantidad de esfuerzo, tiempo y dinero requerido para mantener la calidad será mayor. Pero como siempre decimos dependerá del contexto.
Por ejemplo, en aplicaciones móviles con un fuerte componente de diseño pero poca lógica dentro de la aplicación podríamos recurrir a screenshot testing. Con esta técnica de testing lo que hacemos es «comparamos» en los test capturas de pantalla de la aplicación, por lo que nos aseguramos de que el «look & feel» no se vea modificado.
La matriz de test
Una de los aspectos que hemos comentado durante el post es la confianza que depositamos en nuestros tests. Los test e2e son los que más confianza pueden aportarnos pero en cambio son los que más esfuerzo requieren, los más lentos y frágiles. Así que una alternativa puede ser la matriz de test

Se empieza por la esquina inferior izquierda y a medida que se van añadiendo funcionalidades, tests nos vamos moviendo por la matriz. La idea de la matriz es que el proyecto es algo «vivo» y que a medida que avanzamos la manera de en la que escribimos código/tests cambiará por lo que tenemos que reevaluar donde estamos y hacia donde queremos ir.

Conclusiones
Como vemos hay diferentes aproximaciones a la hora de invertir tiempo en un proyecto software, el modelo de testing que elijamos dependerá como siempre de nuestro contexto: equipo, compañía, tipo de proyecto, velocidad,… al final lo importante se basa en que tengamos tests que nos aporten confianza para poder realizar cambios en el código.
Recursos
- https://franiglesias.github.io/beyond-test-pyramid/
- https://k-hartanto.medium.com/testing-pyramid-and-testing-ice-cream-cone-what-is-the-difference-6ddde3876c20
- https://martinfowler.com/bliki/TestPyramid.html
- https://semaphoreci.com/blog/testing-pyramid
- https://portal.gitnation.org/contents/testing-pyramid-makes-little-sense-what-we-can-use-instead









Replica a La piramide del testing en la CommitConf 2024 – Jesús L.C. – Apuntes de un aprendiz Cancelar la respuesta