¿Qué es la prueba unitaria?
- 10 mins read
- By Marjan Venema
- Updated on abril 26, 2024
Navigate to
Pruebas Unitarias: Un tutorial sobre lo que es, cómo hacerlo y las herramientas que se pueden utilizar
Eso es lo que se oye, al menos.
Pero ¿por qué? ¿Y qué es, de todos modos?
Vamos a profundizar en ello.
¿Qué son las Pruebas Unitarias?
Las pruebas unitarias consisten en verificar el comportamiento de las unidades más pequeñas de su aplicación.
Técnicamente, eso sería una clase o incluso un método de clase en los lenguajes orientados a objetos, y un procedimiento o función en los lenguajes procedimentales y funcionales.
Funcionalmente, puede ser un conjunto de clases estrechamente relacionadas. Como un `Ciervo` y sus clases de apoyo `Cabeza`, `Cola` y `Locomoción`.
Lo que consideres una unidad de trabajo es lo que tenga sentido para ti. No hay reglas estrictas. Siempre y cuando le ayude a entender y pensar en su aplicación.
Eso es diferente a lo que es una prueba de unidad.
¿Qué hace que una prueba unitaria sea una prueba unitaria?
Michael Feathers (autor de «Working Effectively with Legacy Code») sitúa la distinción en el nivel del proceso y del sistema.
Las pruebas unitarias deben ejecutarse de forma aislada porque tienen que ser rápidas.
Todo el conjunto de pruebas unitarias de una aplicación debe ejecutarse en minutos, preferiblemente en segundos. Más adelante se verá por qué.
Por eso las pruebas unitarias no pueden utilizar ningún proceso o sistema externo. No hay operaciones de E/S de ningún tipo (base de datos, archivo, consola, red), excepto el registro de los fallos de las pruebas y quizás la lectura de la configuración de conmutación de características por defecto al inicio de una ejecución de prueba.
Si su código de prueba (o las bibliotecas que utiliza) hace E/S o accede a algo fuera de su proceso, no es una prueba unitaria, sino una prueba de integración.
¿Cuál es el propósito de las pruebas unitarias?
Muchos dicen que el propósito de las pruebas unitarias es validar que cada unidad de trabajo se comporta como se ha diseñado, esperado o previsto. Y que puedes ejecutar tus pruebas unitarias cada vez que alguien haga un cambio. Con sólo pulsar un botón.
Pero el verdadero propósito de las pruebas unitarias es proporcionarle una retroalimentación casi instantánea sobre el diseño y la implementación de su código.
La creación de pruebas unitarias, o más bien la facilidad o dificultad con la que puedes crearlas te dice precisamente cómo de comprobable es su código. Cómo de bien lo ha diseñado. Y si lo escucha, en lugar de usar hacks para superar cualquier dificultad, todos ganan.
He aquí cómo.
¿Cuáles son los beneficios de las pruebas unitarias?
Cómo Escribir Pruebas Unitarias (Usando las Mejores Prácticas)
Crear pruebas unitarias es lo mismo que desarrollar cualquier código, pero hay una diferencia.
Usted crea código de aplicación funcional para resolver un problema para sus clientes.
Usted crea pruebas unitarias para resolver los problemas que surgen en el desarrollo de ese código de aplicación.
Adivine qué significa eso.
Sí, ¡usted es su propio cliente! Y, por supuesto, quiere facilitarse la vida lo máximo posible.
Así que aproveche estas mejores prácticas.
Cuando una prueba depende de cómo otra prueba ha cambiado el entorno (valores de las variables, contenido de las colecciones, etc.), le resultará difícil hacer un seguimiento de las condiciones iniciales de cada prueba. Y lo que es más importante, cuando obtenga resultados inesperados, se preguntará siempre si las condiciones de la prueba o el código de producción los han provocado.
Utilice métodos de configuración y clases de utilidad anidadas si lo desea, pero evite las jerarquías de clases de prueba y las clases de utilidad generales. Se ahorrará tener que cazar entre varias clases base o unidades de clases de utilidad para encontrar los valores que utiliza una prueba.
Cuando una acción deba tener más de un efecto, compruebe cada uno de ellos con un método diferente. Cuando sienta la tentación de utilizar más de una afirmación, pregúntese si está afirmando el hecho más significativo.
Resist the urge to use hacks and “automagic.” Hacks only ever address symptoms, and automagic reduces the transparency you need to figure out why a test fails that should succeed or, worse, why a test succeeds that should fail.
Abordar lo que está causando el dolor utilizando los medios más directos posibles. A menudo, puedes hacer cambios sencillos para que al menos parte de una clase sea más comprobable. Working effectively with Legacy Code de Michael Feathers es un excelente recurso para esto.
Obstáculos comunes en las pruebas unitarias
Los errores más simples pueden hacernos tropezar. Y lo que es peor, pueden hacer que se sienta falsamente seguro.
Una prueba así nunca fallará. Si eso está bien porque simplemente está verificando que no ocurren excepciones, hágalo explícito con un assert y un mensaje apropiado.
Por cierto, está bien utilizar un marco de pruebas unitarias (ver más abajo) para escribir pruebas lentas, pero no son pruebas unitarias, y es mejor mantenerlas en un conjunto de pruebas separado.
Eso le dará dolores de cabeza cuando las pruebas fallen en un entorno y tengan éxito en otro.
Quédese conmigo ahora. Ya casi ha llegado.
Aquí tiene algunas herramientas y técnicas que puedes utilizar.
Herramientas y técnicas de pruebas unitarias
Marcos de pruebas unitarias
Ejecutores de pruebas unitarias
Los ejecutores de pruebas unitarias descubren las pruebas en su código de prueba automáticamente, ejecutan todas las pruebas o una selección específica, y luego informan de los resultados de las pruebas.
Vienen como extensiones del IDE y como utilidades de línea de comandos independientes. Estos últimos pueden utilizarse en los scripts de compilación, para que las compilaciones de integración fallen cuando una fusión rompa el código existente.
Los marcos de pruebas unitarias tienen sus propios ejecutores, pero también se pueden encontrar ejecutores dedicados que pueden descubrir y ejecutar pruebas escritas con múltiples marcos.
Bibliotecas de Imitación
Las librerías de imitación le permiten crear dobles de prueba, o fakes, fácilmente.
Se utilizan para proporcionar a una clase bajo prueba instancias de sus clases colaboradoras. De esta manera, puede personalizar fácilmente el comportamiento de los colaboradores a las necesidades de su prueba.
Inyección de dependencia / Inversión de control
La inversión de control, o inyección de dependencia, es un patrón de diseño que se utiliza para romper los lazos duros entre las clases.
En lugar de que la clase A instancie una clase B5, le proporciona una instancia del ancestro más abstracto de B5 que le da a A los métodos y propiedades que necesita.
Esto hace que las pruebas unitarias de una clase con colaboradores sean más fáciles porque es mucho más fácil proporcionarle falsificaciones.
Entonces, vaya. Pruebe su camino hacia una codificación segura
¡La vida es buena cuando sus equipos ágiles están sincronizados!
Solicite una demostración personalizada de Nimble