Una pirámide de pruebas más simple: cómo aprovechar al máximo sus pruebas
InfoQ Página de inicio Artículos Una pirámide de pruebas más simple: cómo aprovechar al máximo sus pruebas
Este artículo en japonés.
10 de abril de 2023 Lectura de 10 minutos
por
Tyson con mucho gusto
revisado por
matt campbell
Los desarrolladores utilizan muchas etiquetas diferentes para describir sus pruebas automatizadas (unidad, integración, aceptación, componente, servicio, de un extremo a otro, interfaz de usuario, base de datos, sistema, funcional o API). Cada una de estas etiquetas tiene un significado semántico diferente, ya sea describiendo el alcance de la prueba, los tipos de acciones que realiza la prueba, el sujeto de la prueba o los colaboradores del sujeto. Generalmente no estamos de acuerdo sobre lo que significa cada una de estas etiquetas y las discusiones sobre su definición tienden a ser inútiles.
En lugar de discutir sobre qué etiquetas usar y cómo definirlas, me ha resultado más útil usar uno de dos adjetivos para etiquetar cada prueba: lenta o rápida. Estas etiquetas pueden ser igualmente útiles a la hora de decidir la composición de un conjunto de pruebas y, al mismo tiempo, permitir a los desarrolladores clasificar las pruebas objetivamente sin argumentos improductivos.
Codifique, implemente y escale Java a su manera. Microsoft Azure admite su carga de trabajo con abundantes opciones, ya sea que esté trabajando en una aplicación, un servidor de aplicaciones o un marco de Java. Aprende más.
La elección de las etiquetas de prueba es una influencia importante en la composición de un conjunto de pruebas. Los desarrolladores los utilizan para saber cuándo escribir una prueba para un comportamiento determinado, saber qué tipo de prueba escribir y evaluar el equilibrio del conjunto de pruebas en su conjunto. Cuando nos equivocamos, terminamos con un conjunto de pruebas que no brinda una cobertura precisa o que brinda cobertura a un costo inaceptable.
¿Cuándo debería escribir una prueba para un determinado fragmento de código de producción? Los desarrolladores que, como yo, practican la programación extrema (XP) o el desarrollo basado en pruebas (TDD) suelen responder a esta pregunta con "siempre". Sin embargo, no todos los fragmentos de código deben probarse automáticamente. Para cada prueba propuesta, primero compare los costos de redactar la prueba con los beneficios.
No estoy defendiendo la redacción de exámenes. De hecho, para la mayoría de las pruebas, se trata de una comprobación rápida y la respuesta es sí. Sin embargo, esta verificación es útil, especialmente si una prueba es lenta de ejecutar, lenta de escribir o difícil de mantener. En estos casos hágase algunas preguntas.
¿Es costosa la prueba debido a una decisión de diseño? ¿Se puede refactorizar el código para adaptarlo mejor a las pruebas? Sus pruebas son los primeros consumidores de su código de producción. Hacer que el código sea más fácil de probar a menudo hace que sea más fácil de consumir, lo que mejora la calidad de su código base.
¿Es costosa la prueba debido al enfoque de prueba? ¿Un enfoque de prueba diferente haría que esta prueba fuera más fácil de escribir? Considere utilizar dobles de prueba como falsificaciones o simulacros en lugar de colaboradores. Si sus pruebas necesitan una configuración complicada, extráigala a un escenario de prueba que pueda reutilizarse entre pruebas.
Tenga cuidado de no abusar de los dobles de prueba, ya que no brindan tanta confianza como los colaboradores reales. A veces, esta caída en la confianza vale la pena por la facilidad de configuración, la disminución de la duración de la prueba o el aumento de la confiabilidad. Sin embargo, depender demasiado de las pruebas dobles puede acoplar sus pruebas a su implementación, lo que dará como resultado un conjunto de pruebas que proporciona poca confianza y que inhibe la refactorización.
¿Es costosa la prueba porque el comportamiento es inherentemente difícil de probar? Si es así, considere la importancia de la característica que está probando. Si se trata de una característica crítica que implica el procesamiento de pagos, entonces la prueba podría valer la pena. Si se trata de un caso extremo peculiar en su lógica de visualización, entonces debería reconsiderar si escribir o no la prueba.
¿Es costosa la prueba porque falla de manera impredecible? Si es así, debe eliminarlo, reescribirlo para que sea más confiable o separarlo del resto de su conjunto de pruebas. Para que un conjunto de pruebas proporcione comentarios útiles, debe estar seguro de que las fallas de las pruebas representan un comportamiento no deseado. Si considera que una prueba es necesaria y no se puede hacer predecible, muévala a otro conjunto de pruebas que se ejecute con menos frecuencia.
Para ayudar con la decisión de cuándo escribir una prueba y qué tipo de prueba escribir, los desarrolladores suelen colocar etiquetas de prueba en una pirámide de pruebas para comunicar la importancia de tener más de un tipo de prueba que de otro.
Dadas las muchas etiquetas diferentes que se utilizan para describir las pruebas, cada pirámide de pruebas se ve un poco diferente de las demás. Intente realizar una búsqueda de imágenes para "pirámide de prueba" y encontrará sólo unas pocas pirámides duplicadas en la primera página de resultados. Cada pirámide suele tener pruebas unitarias de bajo costo en la parte inferior, pruebas de sistema de alto costo en la parte superior y varias capas de pruebas de costo medio en el medio.
Antes de que un equipo pueda beneficiarse de la pirámide de pruebas, el equipo debe decidir qué etiquetas incluir en la pirámide de pruebas, cuál es la definición de cada etiqueta y en qué orden incluir las etiquetas en la pirámide.
Esta suele ser una decisión polémica, ya que cada desarrollador de un equipo tiende a utilizar un conjunto diferente de etiquetas para describir las pruebas y no existe un amplio acuerdo sobre lo que significa cada etiqueta. De hecho, casi todas las pirámides de pruebas incluyen pruebas unitarias en la parte inferior, pero existe un gran desacuerdo sobre a qué se refiere la palabra "unidad". Este desacuerdo reduce la utilidad de la pirámide de pruebas, ya que las discusiones tienden a girar en torno a las etiquetas en lugar de reducir el costo del conjunto de pruebas.
La velocidad tiende a ser el factor que más contribuye al costo de un conjunto de pruebas. Para obtener comentarios rápidos, los desarrolladores deben ejecutar el conjunto de pruebas varias veces por hora, por lo que incluso un pequeño aumento en el tiempo que lleva ejecutar el conjunto puede generar muchas esperas con el tiempo.
El tiempo dedicado a esperar a que se ejecuten las pruebas es tiempo improductivo. Cuando un conjunto de pruebas es muy lento (tarda más de cinco minutos en ejecutarse), los desarrolladores suelen trabajar en otras tareas mientras se ejecuta la prueba. Este cambio de tareas es perjudicial, ya que disminuye la concentración y hace que el desarrollador pierda contexto. Una vez finalizado el lento conjunto de pruebas, el desarrollador debe tomarse un tiempo adicional para recuperar el contexto antes de continuar con su tarea original.
Centrándose en la velocidad de las pruebas, surge una pirámide de pruebas más simple.
Esta pirámide envía un mensaje claro de que un conjunto de pruebas debe tener tantas pruebas rápidas como sea posible y pruebas lentas suficientes para proporcionar una cobertura completa del comportamiento deseado. Comunica el mismo mensaje que las pirámides de prueba más comunes (y complicadas), pero es mucho más fácil de entender y aceptar para los desarrolladores.
Si bien es posible que diferentes desarrolladores no se pongan de acuerdo sobre dónde colocar una determinada prueba en una pirámide de pruebas común, es fácil saber dónde encaja una prueba determinada en la pirámide anterior. Los equipos sólo tienen que ponerse de acuerdo sobre qué es una prueba rápida y qué es una prueba lenta. Si bien el umbral puede ser diferente según el dominio empresarial, el idioma o el marco, la velocidad de las pruebas se puede medir objetivamente.
Los conjuntos de pruebas siempre comienzan rápido, pero rara vez permanecen así. Con el tiempo se agregan más pruebas y aumenta la tolerancia de los desarrolladores a un conjunto de pruebas lento. Muchos desarrolladores no se dan cuenta de que un conjunto de pruebas rápido es una posibilidad porque nunca han trabajado en una base de código donde el conjunto de pruebas se mantenga rápido.
Mantener rápido un conjunto de pruebas requiere disciplina. Los desarrolladores deben examinar cada vez que añaden elementos a un conjunto de pruebas y darse cuenta del gran beneficio que se obtiene incluso con una pequeña disminución en la duración. Por ejemplo, si un miembro de un equipo de 6 desarrolladores dedica 4 horas a acelerar las pruebas en 10 segundos, esa inversión se amortizará en sólo seis semanas (suponiendo que los desarrolladores ejecuten pruebas una vez por hora durante un día laborable).
Cuando no se controla, la duración de un conjunto de pruebas aumenta exponencialmente con el tiempo. Es decir, la duración aumenta proporcionalmente a la duración actual. Cuando el conjunto se ejecuta en 10 segundos, un desarrollador puede angustiarse por agregar solo un segundo a la compilación, pero una vez que el conjunto de pruebas crece a 3 minutos, es posible que ni siquiera se dé cuenta.
Un método para evitar el crecimiento exponencial es establecer un límite estricto en la duración de su conjunto de pruebas: falle la compilación si su conjunto de pruebas tarda más de, por ejemplo, un minuto en ejecutarse. Si una ejecución de prueba tarda demasiado, la compilación fallará y el desarrollador deberá tomarse un tiempo para acelerar las pruebas antes de continuar. No arregle la compilación simplemente aumentando este límite. Más bien, tómese el tiempo para comprender por qué las pruebas son lentas y cómo puede hacerlas más rápidas.
El código de prueba debe tratarse con el mismo cuidado y escrutinio que el código de producción. Refactorice continuamente para mantener su código de prueba bien estructurado y rápido, minimizando así el costo de mantenimiento y ejecución de su conjunto de pruebas. Tenga en cuenta que las pruebas de refactorización no deben modificar el comportamiento ni del código de prueba ni del código de producción. Más bien, debería cambiar su código para que sea más legible, más fácil de mantener y más rápido de ejecutar.
Si no puede evitar realizar algunas pruebas lentas, agréguelas a un conjunto de pruebas independiente. Este lento conjunto de pruebas no está diseñado para ejecutarse con tanta frecuencia como el conjunto de pruebas principal, pero está ahí para brindar cobertura adicional. No debe bloquear el proceso de compilación, pero debe ejecutarse periódicamente para garantizar que el comportamiento que prueba sigue funcionando correctamente.
No es demasiado tarde para cambiar su enfoque si ha utilizado una pirámide de pruebas diferente para dar forma a su conjunto de pruebas actual. Si ha seguido una pirámide de pruebas más complicada, es probable que muchas de sus pruebas contengan los nombres de las etiquetas de su pirámide de pruebas.
Como primer paso, tómate un tiempo para cambiar el nombre de tus pruebas. Los nuevos nombres de las pruebas deben reflejar el comportamiento bajo prueba en lugar de la etiqueta de la prueba. Por ejemplo, puede cambiar el nombre de UserIntegrationTest a UserAuthenticationTest o RegistrationApiTest a AddPaidUserTest.
Durante este proceso, es probable que encuentres algunas colisiones entre los nuevos nombres. Estas colisiones son una advertencia de que es posible que tenga varias pruebas que cubran el mismo comportamiento. Tómese un tiempo para mover, combinar, cambiar el nombre o eliminar estas pruebas para solucionar la duplicación.
Una vez que se cambie el nombre de sus pruebas, reorganice la estructura del directorio de pruebas para agrupar las pruebas según el comportamiento. Esta organización mantendrá las pruebas que cambian al mismo tiempo cerca unas de otras en su código base y le ayudará a detectar nuevas pruebas que cubran comportamientos duplicados.
Un conjunto de pruebas lento debe abordarse de inmediato. Establezca inmediatamente un límite en la duración del conjunto de pruebas para que no se vuelva más lento. A continuación, agregue alguna instrumentación que le ayude a encontrar las pruebas más lentas enumerando el tiempo de ejecución de cada prueba o grupo de pruebas. Probablemente encontrará algunas pruebas durante este proceso que sean fáciles de acelerar.
Una vez que los solucione, le quedará otro grupo de pruebas lentas que son más difíciles de mejorar. Separe sus pruebas rápidas para poder ejecutarlas por separado de las pruebas lentas restantes. Esto le dará un aumento de velocidad inmediato para algunas ejecuciones de prueba, lo que le permitirá ganar más tiempo para realizar mejoras.
Dedique tiempo a acelerar su prueba de forma regular. Investigue si el comportamiento cubierto por estas pruebas lentas puede ser cubierto (o ya cubierto) por pruebas más rápidas. Un ejemplo común de esto es cubrir muchos casos extremos con pruebas que controlan un navegador. Usar un navegador para ejecutar pruebas requiere mucho tiempo y los comportamientos a menudo pueden cubrirse mediante pruebas de nivel inferior que tienden a ejecutarse más rápido.
Antes de su próxima discusión sobre si escribir, por ejemplo, una prueba del sistema o una prueba de integración, tómese un minuto para pensar. Es probable que descubra que la distinción entre los dos importa poco. Si su objetivo es brindar un alto nivel de confianza y al mismo tiempo minimizar el costo, entonces su argumento es realmente acerca de cómo puede probar el comportamiento deseado con la prueba de menor costo posible. Dirija la discusión en esta dirección y obtendrá un resultado más productivo.
En lugar de centrarse en las etiquetas de las pruebas, concéntrese en lo que es importante: escriba pruebas rápidas. Si tu prueba es lenta, hazla más rápida. Si no puede, intente brindar la misma cobertura con algunas pruebas con un alcance más limitado. Si eso falla, pregúntese si el beneficio que proporciona la prueba vale el costo sustancial de una prueba lenta. Si vale la pena, considere trasladar sus pruebas lentas a un conjunto de pruebas separado que no bloquee la compilación.
Siga esta nueva pirámide de pruebas y concéntrese en la velocidad de las pruebas para mantener su conjunto de pruebas rápido y su confianza alta.
Escribir para InfoQ ha abierto muchas puertas y aumentado las oportunidades profesionales. para mí. Pude interactuar profundamente con expertos y líderes de opinión para aprender más sobre los temas que cubrí. Y también puedo difundir mis conocimientos a la comunidad tecnológica en general y comprender cómo se utilizan las tecnologías en el mundo real.
¡Descubrí el programa de colaboradores de InfoQ a principios de este año y lo he disfrutado desde entonces! Además de brindarme una plataforma para compartir aprendizaje con una comunidad global de desarrolladores de software, el sistema de revisión entre pares de InfoQ ha mejorado significativamente mi escritura. . Si está buscando un lugar para compartir su experiencia en software, comience a contribuir a InfoQ.
Comencé a escribir noticias para la cola InfoQ .NET como una forma de mantenerme actualizado con la tecnología, pero saqué mucho más provecho de ello. Conocí gente conocedora, obtuve visibilidad global y mejoré mis habilidades de escritura..
Convertirme en editor de InfoQ fue una de las mejores decisiones de mi carrera . Me ha desafiado y me ha ayudado a crecer de muchas maneras. . Nos encantaría tener más gente.Unete a nuestro equipo.
InfoQ busca un editor en jefe a tiempo completo para unirse al equipo internacional y siempre remoto de C4Media. Únase a nosotros para cubrir las tecnologías más innovadoras de nuestro tiempo, colabore con los profesionales de software más brillantes del mundo y ayude a más de 1,6 millones de equipos de desarrollo a adoptar nuevas tecnologías y prácticas que superan los límites de lo que el software y los equipos pueden ofrecer.
Todos los martes se envía un resumen del contenido de la semana pasada en InfoQ. Únase a una comunidad de más de 250.000 desarrolladores senior. Ver un ejemplo
Protegemos su privacidad.
Debe registrar una cuenta InfoQ o iniciar sesión o iniciar sesión para publicar comentarios. Pero hay mucho más detrás de estar registrado.
Aproveche al máximo la experiencia InfoQ.
HTML permitido: a,b,br,blockquote,i,li,pre,u,ul,p
por Joan Comas,
por Joan Comas,
Su mensaje está pendiente de moderación. Gracias por participar en la discusión.
Muchas gracias por este artículo tan detallado. Me gustaría agregar que también estoy evaluando el retorno de la inversión de cada prueba. En particular, he estado cuestionando la necesidad de una prueba para clases que hagan una sola cosa que hemos estado haciendo desde siempre. Por ejemplo, no encuentro ningún retorno de la inversión al probar que: - Cuando se agrega una entidad en un Repositorio, la entidad se almacena en la base de datos. - Cuando se llama a un método Send() de una clase que debería enviar datos a través de http, el los datos se envían a través de http.- Cuando se llama a un método Publish() de una clase que debería publicar un evento en una cola, el evento se publica en la cola. Esos repositorios, clientes y editores, nunca deben contener reglas comerciales reales. Y su funcionalidad debería ser trivial hoy en día. Sí, algunas consultas SQL serán más complejas y habrá transacciones y esas cosas, pero luego se trata de crear una infraestructura para encargarse de ello y ESE es el que se prueba adecuadamente en un solo lugar. Además, Cuestiona la necesidad de "pruebas para prohibir", donde los desarrolladores escriben pruebas para asegurarse de que no se utilice alguna dependencia. Y he visto demasiadas. Finalmente, me gustaría mencionar que, cuando sea posible, organice el código por característica (como se hace en Vertical Slice y DDD) para que el grupo de pruebas que lo cubren se pueda ejecutar de forma aislada. ahorrando mucho tiempo. Crear un conjunto de pruebas rápidas no se trata solo de pruebas lentas/rápidas, sino también de aislamiento de pruebas. Hoy en día existen herramientas para ejecutar solo pruebas afectadas, así que utilícelas y ahorre aún más tiempo. De esta manera los desarrolladores no sentirán la necesidad de reducir pruebas lentas importantes sólo por cuestión de tiempo.
HTML permitido: a,b,br,blockquote,i,li,pre,u,ul,p
HTML permitido: a,b,br,blockquote,i,li,pre,u,ul,p
Únase a una comunidad de expertos.Tyson con mucho gustoha abierto muchas puertas y ha aumentado las oportunidades profesionalesVivian HuEl sistema de revisión entre pares de InfoQ ha mejorado significativamente mi escrituraOghenewede EmeniObtuve visibilidad global y mejoré mis habilidades de escritura.Edin Kapicmejores decisiones de mi carrerame ayudó a crecer de muchas manerasUnete a nuestro equipoThomas Bettseditor en jefe a tiempo completoLa información QAproveche al máximo la experiencia InfoQ.por Joan Comas