¿Qué no probar cuando se trata de Pruebas Unitarias?


¿En qué partes de un proyecto escribir pruebas unitarias es casi o realmente imposible? ¿Acceso a datos? ftp?

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

Author: spinodal, 2008-09-21

21 answers

Aquí encontré (vía haacked algo que 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 sus otras pruebas unitarias
  • Tiene que hacer cosas especiales a su entorno (como editar la configuración archivos) para ejecutarlo.

De nuevo en el mismo artículo añade:

Generalmente, 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, sockets o acceso al sistema de archivos en sus pruebas unitarias, ya no se trata realmente de esos métodos; se trata de la integración de su código con ese otro software.

 37
Author: spinodal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-21 06:36:10

Que la cobertura del 100% es un mito, que lo es, no significa que la cobertura del 80% sea inútil. El objetivo, por supuesto, es 100%, y entre las pruebas unitarias y luego las pruebas de integración, puede acercarse a él.

Lo que es imposible en las pruebas unitarias es predecir todas las cosas totalmente extrañas que sus clientes le harán al producto. Una vez que comience a descubrir estas perversiones alucinantes de su código, asegúrese de rodar pruebas para ellos de nuevo en la suite de pruebas.

 13
Author: Kevin Little,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 21:24:17

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

Nada es imposible de probar unitariamente, pero siempre hay rendimientos decrecientes. Puede que no valga la pena hacer pruebas unitarias de cosas que son dolorosas.

 10
Author: Aaron Jensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 21:25:16

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 prueba unitaria que sea difícil 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 asequible.

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

Si el problema que detecta la prueba es 'caro', entonces puede darse el lujo de esforzarse para averiguar cómo probarlo y mantener esa prueba. Si el problema de las capturas de prueba es trivial a continuación, la escritura (y el mantenimiento!) la prueba (incluso en presencia de cambios de código) es mejor que sea trivial.

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

 7
Author: Steve Steiner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-21 05:05:29

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

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

 4
Author: quamrana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 21:44:16

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

 3
Author: Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-21 00:08:59

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

Generalmente, las cosas 'no probables' son FTP, correo electrónico, etc. Sin embargo, generalmente son clases de framework en las que puede confiar y, por lo tanto, no es necesario probar si las oculta detrás de una abstracción.

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

 3
Author: Garry Shutler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-26 05:12:58

@ GarryShutler

Realmente pruebo 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 /

Probablemente se podría hacer algo así para otros servidores. De lo contrario, debería ser capaz de burlarse de la API...

POR cierto: la cobertura del 100% es solo el comienzo... solo significa que todo el código ha sido ejecutado una vez.... nada sobre casos extremos, etc.

 2
Author: p3t0r,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 21:27:49

La mayoría de las pruebas que necesitan configuraciones enormes y costosas (en costo de recursos o tiempo de computación) son pruebas de integración. Las pruebas unitarias deben (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 mock-mailer. El propósito de ese simulacro es asegurarse de que su código llame al correo correctamente. 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 fácilmente posible ejecutar todas sus pruebas unitarias antes de verificar su código.

Sin embargo, si su conjunto de pruebas consta de muchas pruebas de integración (que configuran y derriban bases de datos y similares), su ejecución de 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 se registre.

Así que para responder a su pregunta: unidad-prueba cosas, que se implementan mejor como una prueba de integración (y también no prueba getter/setter - es una pérdida de tiempo ;-) ).

 2
Author: Mo.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 21:49:43

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

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

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 utilizando las herramientas adecuadas.

 2
Author: Angelo van der Sijpt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-21 00:10:36

"¿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 gastarse mejor probando otra cosa.

 2
Author: Vivek Kodira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-21 03:43:11

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

Dicho esto, las pruebas unitarias no deberían ser el único nivel de pruebas en su aplicación. Lograr una cobertura de prueba unitaria del 100% es a menudo una pérdida de tiempo y cumple rápidamente con los 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 funciona correctamente "una vez que todo está unido" - que las pruebas unitarias por definición no prueba.

 2
Author: madlep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-29 10:48:51

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

 1
Author: EricSchaefer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 21:24:36

Puedes probarlos, pero no serán pruebas unitarias. La prueba unitaria es algo que no cruza los límites, como cruzar el cable, golpear la base de datos, ejecutar/interactuar con un tercero, Tocar una base de código no probada/heredada, etc.

Cualquier cosa más allá de esto son pruebas de integración.

La respuesta obvia de la pregunta en el título es que no debe probar unitariamente las funciones internas de su API, no debe confiar en el comportamiento de otra persona, no debe probar nada que usted no es responsable.

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

 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 22:04:23

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 corregir uno o dos errores antes de la implementación no necesariamente vale la pena el tiempo para crear pruebas unitarias exhaustivas.

Probar exhaustivamente 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 escribe necesite un nivel muy alto de confiabilidad (99.999% de cosas) fregadero en tiempo real.

 1
Author: wprl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 22:31:22

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

 1
Author: Mitch Wheat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-21 06:50:04

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

 1
Author: Adron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-20 19:18:45

FTP, SMTP, E/S en general deben ser probados usando una interfaz. La interfaz debe ser implementada por un adaptador (para el código real) y un simulacro para la prueba unitaria.

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

 1
Author: Andrei Rînea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-07 23:02:26

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

 0
Author: Rob Walker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 21:24:05

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

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

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

 0
Author: Horcrux7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 21:29:00

La razón principal para probar el código unitario 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, son para desarrolladores y sistemas de compilación para usar para validar un sistema antes del lanzamiento. Con ese fin, las pruebas unitarias deben ejecutarse muy rápido y tener la menor fricción de configuración y dependencia posible. Tratar de hacer tanto como pueda en memoria, y evitar el uso de conexiones de red de las pruebas.

 0
Author: Kris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 21:51:37