Pregunta

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

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

¿Fue útil?

Solución

Aquí encontré (a través de pirateado algo que dice Michael Feathers 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 puede ejecutarse al mismo tiempo que ninguna de sus 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:

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

Otros consejos

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

Lo que es imposible en las pruebas unitarias es predecir todos los extraño cosas que sus clientes harán con el producto.Una vez que comience a descubrir estas perversiones alucinantes de su código, asegúrese de realizar pruebas nuevamente en el conjunto de pruebas.

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

Nada es imposible de realizar una prueba unitaria, pero siempre hay rendimientos decrecientes.Puede que no valga la pena realizar pruebas unitarias de cosas que son difíciles de realizar.

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

El objetivo de cualquier prueba es detectar problemas visibles para el usuario de la manera más asequible.

¿Vale la pena el costo total de creación, mantenimiento y diagnóstico de los problemas señalados por la prueba (incluidos los falsos positivos) en comparación con los problemas que detecta una prueba específica?

Si el problema que detecta la prueba es "caro", entonces puede darse el lujo de esforzarse en descubrir cómo probarlo y mantener esa prueba.Si el problema que detecta la prueba es trivial, entonces es mejor escribir (¡y mantener!) la prueba (incluso en presencia de cambios de código) que sea trivial.

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

¿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 ni el código del sistema operativo, ya que ese código se le habrá entregado probado.A menos que no sea así.En cuyo caso quizás quieras probarlo.O si hay errores conocidos, en cuyo caso es posible que desee probar la presencia de los errores, para recibir una notificación cuando se solucionen.

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

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

Generalmente, 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 realizar pruebas si las oculta detrás de una abstracción.

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

@GarryShutler

De hecho, realizo una prueba unitaria del correo electrónico utilizando un servidor smtp falso (Wiser).Se asegura de que el código de su 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í con otros servidores.De lo contrario, deberías poder burlarte de la API...

POR CIERTO:Cobertura del 100% es sólo el comienzo...solo significa que todo el código realmente se ha ejecutado una vez....nada sobre casos extremos, etc.

La mayoría de las pruebas, que necesitan configuraciones enormes y costosas (en costo de recursos o tiempo de cálculo) 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 del correo electrónico, tiene sentido crear un remitente simulado.El propósito de ese simulacro es asegurarse de que su código llame al remitente de 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 deberían ejecutarse muy rápido.Debería ser posible ejecutar fácilmente todas las pruebas unitarias antes de registrar su código.

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

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

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

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

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

"¿Qué no probar cuando se trata de pruebas unitarias?" * Frijoles con solo Getters y Setters.Razonamiento:Por lo general, es una pérdida de tiempo que podría aprovecharse mejor probando otra cosa.

Todo lo 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 rarezas como subprocesos, generación aleatoria de datos, horas/fechas o servicios externos pueden afectar esto, entonces no debería cubrirlo en sus pruebas unitarias. .Las horas/fechas son un caso particularmente desagradable.Por lo general, puede diseñar el código para inyectar una fecha con la que trabajar (mediante código y pruebas) en lugar de depender de la funcionalidad en la fecha y hora actuales.

Dicho esto, las pruebas unitarias no deberían ser el único nivel de prueba en su aplicación.Lograr una cobertura de pruebas unitarias del 100 % suele ser una pérdida de tiempo y rápidamente genera 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 esté todo unido" - que la unidad prueba por definición no prueba.

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

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

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

La respuesta obvia a la pregunta del título es No debes realizar pruebas unitarias de los componentes internos de tu API, no debes confiar en el comportamiento de otra persona, no debes probar nada de lo que no seas responsable.

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

Seguro que una cobertura del 100% es buena. meta 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 para crear pruebas unitarias exhaustivas.

Probar exhaustivamente cosas como el envío de formularios, el acceso a bases de datos, el acceso FTP, etc. a un nivel muy detallado suele ser sólo una pérdida de tiempo;A menos que el software que se está escribiendo necesite un nivel muy alto de confiabilidad (99,999% de cosas), las pruebas unitarias excesivas pueden ser excesivas y consumir tiempo real.

No estoy de acuerdo con la respuesta de quamrana con respecto a no probar el 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 una biblioteca de terceros, se ejecutan las pruebas unitarias que representan el comportamiento esperado de esta biblioteca para verificar que todavía funciona como se esperaba.

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 realizarse según la configuración.Esto reduce la redundancia de pruebas y libera mucho tiempo.Intentar realizar una prueba unitaria de la configuración suele ser frívolo.

FTP, SMTP, E/S en general deben 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 unitaria debe ejercitar el recurso externo real (servidor FTP, etc.)

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 va a 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.

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

No se pueden probar algunos errores de manejo.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 arrojará.O el caso predeterminado de un cambio si para todos los casos posibles existe un bloque de casos.

Por supuesto, se pueden eliminar algunos de los controles de errores innecesarios.Pero si hay un error de codificación en el futuro, entonces esto es malo.

La razón principal para realizar una prueba unitaria del código 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 utilizar objetos simulados o alguna forma de aislamiento o inyección de dependencia.

Recuerde, las pruebas unitarias no son para usuarios, son para que los desarrolladores y los sistemas de compilación las utilicen para validar un sistema antes de su lanzamiento.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 la memoria y evite utilizar conexiones de red durante las pruebas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top