Looking for unit-testing Answers? Try Ask4KnowledgeBase
Looking for unit-testing Keywords? Try Ask4Keywords

unit-testingLas reglas generales para la prueba unitaria para todos los idiomas.


Introducción

Al comenzar con la prueba unitaria surgen todo tipo de preguntas:

¿Qué es la prueba unitaria? ¿Qué es un SetUp y TearDown? ¿Cómo trato con las dependencias? ¿Por qué hacer pruebas de unidad en absoluto? ¿Cómo hago buenas pruebas unitarias?

Este artículo responderá todas estas preguntas, para que pueda comenzar la prueba de unidad en el idioma que desee.

Observaciones

¿Qué es la prueba unitaria?

La prueba unitaria es la prueba del código para garantizar que realiza la tarea que debe realizar. Prueba el código en el nivel más bajo posible: los métodos individuales de sus clases.

¿Qué es una unidad?

Cualquier módulo discreto de código que pueda ser probado de forma aislada. La mayoría de las clases de tiempo y sus métodos. Esta clase se conoce generalmente como la "Clase bajo prueba" (CUT) o el "Sistema bajo prueba" (SUT)

La diferencia entre las pruebas unitarias y las pruebas de integración.

La prueba de unidad es el acto de probar una sola clase en forma aislada, completamente aparte de cualquiera de sus dependencias en realidad. La prueba de integración es el acto de probar una sola clase junto con una o más de sus dependencias reales.

El SetUp y TearDown

Cuando se realiza, el método de configuración se ejecuta antes de cada prueba de unidad y el TearDown después de cada prueba.

En general, agrega todos los pasos de requisitos previos en la Configuración y todos los pasos de limpieza en el TearDown. Pero solo crea estos métodos si estos pasos son necesarios para cada prueba. Si no, que estos pasos se toman dentro de las pruebas específicas en la sección "organizar".

Como lidiar con las dependencias.

Muchas veces una clase tiene la dependencia de otras clases para ejecutar sus métodos. Para poder no depender de estas otras clases, tienes que falsificarlas. Puede crear estas clases usted mismo o usar un marco de aislamiento o de maqueta. Un marco de aislamiento es una colección de código que permite la creación fácil de clases falsas.

Clases falsas

Cualquier clase que proporcione funcionalidad suficiente para pretender que es una dependencia que necesita un CUT. Hay dos tipos de falsificaciones: Stubs y Mocks.

  • Un código auxiliar: un falso que no tiene ningún efecto en la aprobación o el fracaso de la prueba y que existe únicamente para permitir que la prueba se ejecute.
  • Un simulacro: un falso que realiza un seguimiento del comportamiento de la CUT y pasa o falla la prueba basada en ese comportamiento.

¿Por qué pruebas de unidad?

1. Las pruebas unitarias encontrarán errores.

Cuando escribe un conjunto completo de pruebas que definen cuál es el comportamiento esperado para una clase determinada, se revela todo lo que no se comporta como se espera.

2. La prueba de la unidad mantendrá a los insectos alejados

Realice un cambio que introduzca un error y sus pruebas pueden revelarlo la próxima vez que ejecute las pruebas.

3. La prueba de la unidad ahorra tiempo

Escribir pruebas unitarias ayuda a garantizar que su código funcione correctamente desde el principio. Las pruebas unitarias definen lo que su código debe hacer y, por lo tanto, no pasará tiempo escribiendo un código que haga cosas que no debería hacer. Nadie comprueba en el código que no cree que funcione y usted tiene que hacer algo para hacerse creer que funciona. Pasa ese tiempo para escribir pruebas unitarias.

4. La prueba de unidad le da tranquilidad.

Puede ejecutar todas esas pruebas y saber que su código funciona como se supone. Saber el estado de su código, que funciona y que puede actualizarlo y mejorarlo sin temor es algo muy bueno.

5. Las pruebas unitarias documentan el uso adecuado de una clase.

Las pruebas unitarias se convierten en ejemplos simples de cómo funciona su código, qué se espera que haga y la forma correcta de usar su código que se está probando.

Reglas generales para la prueba unitaria.

1. Para la estructura de una prueba unitaria, siga la regla AAA

Organizar:

Configurar la cosa para ser probado. Me gustan las variables, los campos y las propiedades para permitir que la prueba se ejecute así como el resultado esperado.

Actúa: llama al método que estás probando.

Afirmar:

Llame al marco de pruebas para verificar que el resultado de su "acto" sea el esperado.

2. Prueba una cosa a la vez en aislamiento

Todas las clases deben ser probadas en aislamiento. No deben depender de otra cosa que no sean las burlas y los talones. No deben depender de los resultados de otras pruebas.

3. Escribe primero las pruebas simples "justo en el medio"

Las primeras pruebas que escriba deben ser las pruebas más simples. Deben ser los que, básicamente, ilustran fácilmente la funcionalidad que intenta escribir. Luego, una vez que esas pruebas pasan, debe comenzar a escribir las pruebas más complicadas que prueban los bordes y límites de su código.

4. Escribir pruebas que prueben los bordes.

Una vez que se prueban los conceptos básicos y sabes que tu funcionalidad básica funciona, debes probar los bordes. Un buen conjunto de pruebas explorará los bordes externos de lo que podría suceder con un método determinado.

Por ejemplo:

  • ¿Qué pasa si se produce un desbordamiento?
  • ¿Qué pasa si los valores van a cero o por debajo?
  • ¿Qué pasa si van a MaxInt o MinInt?
  • ¿Qué pasa si creas un arco de 361 grados?
  • ¿Qué pasa si pasas una cadena vacía?
  • ¿Qué sucede si una cadena tiene un tamaño de 2 GB?

5. Prueba a través de los límites

Las pruebas unitarias deben probar ambos lados de un límite dado. Moverse a través de los límites son lugares donde su código puede fallar o funcionar de manera impredecible.

6. Si puedes, prueba todo el espectro.

Si es práctico, pruebe todo el conjunto de posibilidades para su funcionalidad. Si se trata de un tipo enumerado, pruebe la funcionalidad con cada uno de los elementos de la enumeración. Puede que no sea práctico probar todas las posibilidades, pero si puede probar todas las posibilidades, hágalo.

7. Si es posible, cubra cada ruta de código

Este también es un desafío, pero si su código está diseñado para pruebas y usted utiliza una herramienta de cobertura de códigos, puede asegurarse de que cada línea de su código esté cubierta por pruebas unitarias al menos una vez. La cobertura de cada ruta de código no garantiza que no haya errores, pero seguramente le brinda información valiosa sobre el estado de cada línea de código.

8. Escriba pruebas que revelen un error, luego corríjalo

Si encuentras un error, escribe una prueba que lo revele. Luego, puedes corregir fácilmente el error al depurar la prueba. Luego tienes una buena prueba de regresión para asegurarte de que si el error regresa por alguna razón, lo sabrás de inmediato. Es realmente fácil corregir un error cuando tiene una prueba simple y directa para ejecutar en el depurador.

Un beneficio adicional aquí es que has probado tu prueba. Debido a que ha visto fallar la prueba y luego, cuando la ha pasado, sabe que la prueba es válida porque se ha demostrado que funciona correctamente. Esto hace que sea una prueba de regresión aún mejor.

9. Hacer que cada prueba sea independiente la una de la otra.

Las pruebas nunca deben depender unas de otras. Si sus pruebas tienen que ejecutarse en un cierto orden, necesita cambiar las pruebas.

10. Escribe un aserto por prueba

Usted debe escribir una aserción por prueba. Si no puede hacer eso, refractor su código para que sus eventos SetUp y TearDown se usen para crear correctamente el entorno para que cada prueba se pueda ejecutar de forma individual.

11. Nombra tus pruebas claramente. No tengas miedo de los nombres largos

Ya que estás haciendo una aseveración por prueba, cada prueba puede terminar siendo muy específica. Por lo tanto, no tenga miedo de usar nombres largos y completos de pruebas.

Un nombre largo y completo le permite saber de inmediato qué prueba falló y exactamente qué intentaba hacer la prueba.

Las pruebas largas y claramente nombradas también pueden documentar sus pruebas. Una prueba llamada "DividedByZeroShouldThrowException" documenta exactamente lo que hace el código cuando intenta dividir por cero.

12. Prueba de que cada excepción planteada es realmente levantada

Si su código genera una excepción, escriba una prueba para asegurarse de que todas las excepciones que en realidad genere se produzcan cuando se supone que deben hacerlo.

13. Evita el uso de CheckTrue o Assert.IsTrue

Evite verificar si hay una condición booleana. Por ejemplo, en lugar de verificar si dos cosas son iguales a CheckTrue o Assert.IsTrue, use CheckEquals o Assert.IsEqual en su lugar. ¿Por qué? Debido a esto:

CheckTrue (esperado, real) Esto informará algo como: "Algunas pruebas fallaron: se esperaba que fuera cierto, pero el resultado real fue falso".

Esto no te dice nada.

CheckEquals (Esperado, Actual)

Esto le dirá algo como: "Algunas pruebas fallaron: Se esperaba 7 pero el resultado real fue 3".

Solo use CheckTrue o Assert.IsTrue cuando su valor esperado sea realmente una condición booleana.

14. Realiza tus pruebas constantemente.

Ejecute sus pruebas mientras escribe el código. Sus pruebas deben ejecutarse rápidamente, lo que le permite ejecutarlas incluso después de cambios menores. Si no puede ejecutar sus pruebas como parte de su proceso de desarrollo normal, entonces algo va mal. Se supone que las pruebas unitarias se ejecutan casi al instante. Si no lo están, probablemente es porque no los estás ejecutando de forma aislada.

15. Ejecute sus pruebas como parte de cada compilación automatizada

Del mismo modo que debería realizar la prueba mientras se desarrolla, también deben ser parte integral de su proceso de integración continua. Una prueba fallida debe significar que tu construcción está rota. No dejes que las pruebas que fallan permanezcan. Considéralo un fallo de compilación y repáralo inmediatamente.

Las reglas generales para la prueba unitaria para todos los idiomas. Ejemplos relacionados