unitarias tipos pruebas plan para metodologia interfaz funcionales ejemplo diseñar unit-testing language-agnostic tdd testing-strategies

unit-testing - tipos - pruebas unitarias interfaz



¿Qué no probar cuando se trata de pruebas unitarias? (23)

¿En qué partes de las pruebas de unidades de escritura de proyectos es casi o realmente imposible? ¿Acceso a los datos? ftp?

Si hay una respuesta a esta pregunta, la cobertura% 100 es un mito, ¿no?


¿Qué no probarías? Cualquier cosa que no pueda romperse.

Cuando se trata de la cobertura del código, debe apuntar al 100% del código que realmente escribe; es decir, no necesita probar el código de la biblioteca de terceros ni el código del sistema operativo, ya que el código se le habrá entregado. A menos que no sea así. En ese caso, es posible que desee probarlo. O si hay errores conocidos, en cuyo caso es posible que desee probar la presencia de los errores, de modo que reciba una notificación de cuándo se solucionan.


@GarryShutler

En realidad, compruebo el correo electrónico usando un servidor smtp falso (Wiser). Se asegura de que el código de la aplicación sea correcto:

http://maas-frensch.com/peter/2007/08/29/unittesting-e-mail-sending-using-spring/

Algo como eso probablemente podría hacerse para otros servidores. De lo contrario, deberías poder burlarte de la API ...

Por cierto: la cobertura del 100% es solo el comienzo ... solo significa que todo el código se ha ejecutado realmente una vez ... nada acerca de los casos extremos, etc.


Cualquier cosa que necesite una configuración muy grande y complicada. Por supuesto, puede probar ftp (cliente), pero luego debe configurar un servidor ftp. Para la prueba unitaria necesita una configuración de prueba reproducible. Si no puede proporcionarlo, no puede probarlo.


Esa cobertura del 100% es un mito, lo que es, no significa que la cobertura del 80% es inútil. El objetivo, por supuesto, es 100%, y entre pruebas unitarias y luego pruebas de integración, puede abordarlo.

Lo que es imposible en las pruebas unitarias es predecir todas las cosas totalmente extrañas que sus clientes harán con el producto. Una vez que comienzas a descubrir estas perversiones alucinantes de tu código, asegúrate de volver a pasar las pruebas al conjunto de pruebas.


FTP, correo electrónico, etc., puede probar con una emulación de servidor. Es difícil pero posible.

No se puede verificar el manejo de errores. En cada código hay un manejo de errores que nunca puede ocurrir. Por ejemplo, en Java debe haber muchas excepciones porque es parte de una interfaz. Pero la instancia utilizada nunca lo arrojará. O el caso predeterminado de un interruptor si para todos los casos posibles existe un bloque de casos.

Por supuesto, se puede eliminar parte del manejo de errores no necesarios. Pero hay un error de codificación en el futuro, entonces esto es malo.


La mayoría de las pruebas, que requieren configuraciones enormes y costosas (en costo de recursos o tiempos de computación) son pruebas de integración. Las pruebas unitarias deberían (en teoría) solo probar pequeñas unidades del código. Funciones individuales

Por ejemplo, si está probando la funcionalidad de correo electrónico, tiene sentido crear un falso envío de correo. El objetivo de ese simulacro es asegurarse de que su código llame correctamente al remitente. Para ver si su aplicación realmente envía correo es una prueba de integración.

Es muy útil hacer una distinción entre pruebas unitarias y pruebas de integración. Las pruebas unitarias deben ejecutarse muy rápido. Debería ser posible ejecutar todas las pruebas de su unidad antes de verificar su código.

Sin embargo, si su suite de pruebas consta de muchas pruebas de integración (que configuran y destruyen bases de datos y similares), su prueba puede exceder fácilmente media hora. En ese caso, es muy probable que un desarrollador no ejecute todas las pruebas unitarias antes de que ingrese.

Entonces, para responder a su pregunta: haga pruebas netas de la unidad, que se implementan mejor como una prueba de integración (y tampoco pruebe getter / setter; es una pérdida de tiempo ;-)).


La razón principal para el código de prueba unitaria en primer lugar es validar el diseño de su código. Es posible obtener una cobertura de código del 100%, pero no sin usar objetos simulados o alguna forma de aislamiento o inyección de dependencia.

Recuerde, las pruebas unitarias no son para usuarios, sino para que los desarrolladores y los sistemas de compilación las utilicen para validar un sistema antes de la publicación. Para ello, las pruebas unitarias deben ejecutarse muy rápido y tener la menor fricción de configuración y dependencia posible. Intente hacer todo lo que pueda en memoria y evite usar conexiones de red de las pruebas.


Puedes probarlos, pero no serán pruebas unitarias. La prueba de unidad es algo que no traspasa los límites, como cruzar el cable, acceder a la base de datos, ejecutar / interactuar con un tercero, tocar una base de código no comprobada / heredada, etc.

Cualquier cosa más allá de esto es la prueba de integración.

La respuesta obvia de la pregunta en el título es que no debe probar la unidad interna de su API, no debe confiar en el comportamiento de otra persona, no debe probar nada de lo que no es responsable.

El resto debería ser suficiente para que solo puedas escribir tu código dentro de él, ni más ni menos.


Seguro que la cobertura del 100% es un buen objetivo cuando se trabaja en un proyecto grande, pero para la mayoría de los proyectos la solución de uno o dos errores antes de la implementación no necesariamente vale la pena el tiempo para crear pruebas unitarias exhaustivas.

Exhaustivamente probar cosas como el envío de formularios, el acceso a la base de datos, el acceso FTP, etc. a un nivel muy detallado a menudo es solo una pérdida de tiempo; a menos que el software que se está escribiendo necesite un nivel muy alto de confiabilidad (99,999% de material), las pruebas unitarias en exceso pueden ser exageradas y un sumidero en tiempo real.


Si el código para configurar el estado requerido para una prueba unitaria se vuelve significativamente más complejo que el código que se probará, tiendo a trazar la línea y encontrar otra forma de probar la funcionalidad. En ese punto, debes preguntar cómo sabes que la prueba unitaria es correcta.


lograr una cobertura de código del 100% casi siempre es un desperdicio. Hay muchos recursos en esto.

Nada es imposible de probar por unidad, pero siempre hay rendimientos decrecientes. Puede que no valga la pena probar cosas que son dolorosas para la prueba unitaria.


"¿Qué no probar cuando se trata de pruebas unitarias?" * Frijoles con solo getters y setters. Razonamiento: por lo general, una pérdida de tiempo que podría ser mejor invertida en probar otra cosa.


El objetivo no es una cobertura de código del 100% ni una cobertura de código del 80%. Una prueba unitaria que sea fácil de escribir no significa que deba escribirla, y una unidad que las pruebas sean difíciles de escribir no significa que deba evitar el esfuerzo.

El objetivo de cualquier prueba es detectar los problemas visibles del usuario de la manera más refinada.

¿El costo total de crear, mantener y diagnosticar problemas marcados por la prueba (incluidos los falsos positivos) justifica los problemas que detecta la prueba específica?

Si el problema que detecta la prueba es "costoso", entonces puede permitirse esforzarse en averiguar cómo probarlo y en mantener esa prueba. Si el problema que atrapa la prueba es trivial, entonces escribir (¡y mantener!) La prueba (incluso en presencia de cambios de código) es mejor que sea trivial.

El objetivo central de una prueba unitaria es proteger a los desarrolladores de los errores de implementación. Solo eso debería indicar que demasiado esfuerzo será un desperdicio. Después de cierto punto, hay mejores estrategias para lograr una implementación correcta. Además, después de cierto punto, los problemas visibles del usuario se deben a la correcta implementación de lo incorrecto, que solo puede detectarse mediante el nivel de usuario o las pruebas de integración.


En las pruebas unitarias, no debe probar nada que no pertenezca a su unidad; probar unidades en su contexto es una cuestión diferente. Esa es la respuesta simple.

La regla básica que uso es que debes probar lo que toque los límites de tu unidad (generalmente clase, o cualquier otra cosa que tu unidad pueda ser) y burlarte del resto. No es necesario probar los resultados que devuelve alguna consulta de base de datos, basta con probar que su unidad escupe la consulta correcta.

Esto no significa que no deba omitir cosas que son difíciles de probar; incluso el manejo de excepciones y los problemas de concurrencia se pueden probar bastante bien usando las herramientas adecuadas.


Las pruebas unitarias de una GUI también son difíciles, aunque no imposibles, supongo.


No estoy de acuerdo con la respuesta de quamrana sobre no probar el código de un tercero. Este es un uso ideal de una prueba unitaria. ¿Qué pasa si los errores se introducen en una nueva versión de una biblioteca? Idealmente, cuando se lanza una nueva versión de una biblioteca de terceros, ejecuta las pruebas unitarias que representan el comportamiento esperado de esta biblioteca para verificar que siga funcionando como se esperaba.


Aquí encontré (a través de algo hackeado Michael Feathers dice que puede ser una respuesta:

Él dice,

Una prueba no es una prueba unitaria si:

  • Habla con la base de datos
  • Se comunica a través de la red
  • Toca el sistema de archivos
  • No se puede ejecutar al mismo tiempo que cualquiera de tus otras pruebas unitarias
  • Tienes que hacer cosas especiales en tu entorno (como editar archivos de configuración) para ejecutarlo.

Nuevamente en el mismo artículo agrega:

En general, se supone que las pruebas unitarias son pequeñas, prueban un método o la interacción de un par de métodos. Cuando extrae la base de datos, los sockets o el acceso al sistema de archivos en las pruebas de su unidad, ya no se trata realmente de esos métodos; se trata de la integración de su código con ese otro software.


La configuración es otro elemento que es muy difícil de probar bien en las pruebas unitarias. Las pruebas de integración y otras pruebas deben hacerse contra la configuración. Esto reduce la redundancia de las pruebas y libera mucho tiempo. Intentar la configuración de prueba unitaria a menudo es frívolo.


Cualquier cosa que no sea completamente determinista es un no-no para pruebas unitarias. Desea que las pruebas de su unidad SIEMPRE superen o fallen con las mismas condiciones iniciales: si las rarezas como el enhebrado, la generación aleatoria de datos, la hora o las fechas o los servicios externos pueden afectar esto, entonces no debería cubrirlo en las pruebas de su unidad . Hora / fechas son un caso particularmente desagradable. Por lo general, puede diseñar código para tener una fecha para trabajar con ser inyectado (por código y pruebas) en lugar de confiar en la funcionalidad en la fecha y hora actual.

Sin embargo, dicho esto, las pruebas unitarias no deberían ser el único nivel de prueba en su aplicación. Lograr una cobertura de prueba unitaria del 100% es a menudo una pérdida de tiempo, y rápidamente cumple con rendimientos decrecientes.

Mucho mejor es tener un conjunto de pruebas funcionales de nivel superior, e incluso pruebas de integración para garantizar que el sistema funcione correctamente "una vez que todo esté unido" , lo que las pruebas de la unidad, por definición , no prueban.



El acceso a datos es posible porque puede configurar una base de datos de prueba.

En general, las cosas "no comprobables" son FTP, correo electrónico, etc. Sin embargo, generalmente son clases marco en las que puede confiar y, por lo tanto, no es necesario que las pruebe si las oculta detrás de una abstracción.

Además, la cobertura del 100% del código no es suficiente por sí misma.


FTP, SMTP, E / S en general deberían probarse utilizando una interfaz. La interfaz debe implementarse mediante un adaptador (para el código real) y un simulacro para la prueba unitaria.

Ninguna prueba de unidad debe ejercer el recurso externo real (servidor FTP, etc.)