2008-09-20 13 views
33

¿En qué partes de las pruebas de unidad de escritura de proyecto es casi o realmente imposible? ¿Acceso a los datos? ftp?¿Qué no se debe probar cuando se trata de pruebas unitarias?

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

+0

Por qué no fue este cerrado como un duplicado? http://stackoverflow.com/questions/62625/how-do-you-know-what-to-test-when-writing-unit-tests, http://stackoverflow.com/questions/61400/what-makes- a-good-unit-test, etc. – raven

+3

Creo que esas tres preguntas son diferentes y deben discutirse en diferentes páginas. – spinodal

+0

La cobertura del código del 100% no es un mito, es una asíntota. – James

Respuesta

35

Here me pareció (a través de haacked algo Michael plumas dice que puede haber una respuesta:

Dice,

Una prueba no es una prueba de unidad si:

  • Habla con la base de datos
  • Se comunica a través de la red
  • Toca el sistema de archivos
  • No puede ejecutar al mismo tiempo que cualquiera de su otra unidad de pruebas
  • Tienes que hacer cosas especiales para su entorno (por ejemplo, archivos de configuración de edición) para ejecutarlo.

De nuevo en mismo artículo añade:

En general, se supone que las pruebas unitarias para ser pequeño, que ponen a prueba 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.

+0

Estoy completamente en desacuerdo con esto. ¿Qué pasa si el código según la base de datos se refactoriza? – Sklivvz

+2

@Skliwz: Para eso están las interfaces/clases abstractas y los objetos simulados. Si está bien diseñado y la base de datos se refactoriza, las clases afectadas solo necesitan tener en cuenta la interfaz de la base de datos. – Spoike

3

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

+0

Las pruebas basadas en una base de datos de prueba todavía pueden fallar debido a problemas de red, a menos que se refiriera a una base de datos en memoria. –

+0

Me alegra ver a alguien abogando por las pruebas con datos reales. En general, simulamos algunos datos, pero utilizamos nuestra base de datos para garantizar que las pruebas sean válidas. –

+0

pero hablar con una base de datos de prueba sería una prueba de integración y no una prueba de unidad ... ¿No es así? –

0

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.

12

Que la 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 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.

1

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.

10

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

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

2

@GarryShutler

En realidad unittest de correo electrónico mediante un servidor SMTP falso (Wiser). Se asegura de que el código de aplicación es correcta:

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

Algo así como que probablemente se podría hacer para otros servidores. De lo contrario, debe ser capaz de burlarse de la API ...

BTW: 100% de cobertura es sólo el principio ... sólo significa que todo el código tiene en realidad frijol ejecutado una vez .... nada sobre casos extremos, etc.

+0

Sí, esto es posible, pero ¿sigue siendo una prueba unitaria, entonces? ¿Dónde trazas la línea entre las pruebas unitarias y las pruebas de integración? – philant

+0

Tienes razón; usar servidores falsos sería una prueba de integración ... burlarse de sus interfaces sería una prueba unitaria. – p3t0r

0

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

No se puede comprobar 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 tratamiento de errores no necesarios. Pero hay un error de codificación en el futuro, entonces esto es malo.

4

¿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 código de biblioteca de terceros o código de sistema operativo ya que el código se le habrá entregado probado . 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.

+0

"¿Qué no probarías? Cualquier cosa que no pueda romperse". Obviamente, tales cosas no existen;) – Thomas

+0

Me parece que lo que no se puede romper es dónde están los errores más difíciles de encontrar. ¿Me pregunto porque? –

+1

¡Continuamos! Solo estoy citando el pensamiento Agile convencional: prueba todo lo que podría romperse. Las cosas como los accesorios se consideran "irrompibles", por lo que no es necesario realizar una prueba explícita, solo se prueban durante el curso de la prueba de otra cosa. – quamrana

2

mayoría de las pruebas, que necesitan enormes y caros (en el costo de los recursos o computationtime) son configuraciones de 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 correo electrónico-funcionalidad, tiene sentido, para crear una maqueta 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 la unidad de pruebas 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 banco 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 se registre.

Para responder a su pregunta: realice 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 ;-)).

0

La principal razón para código de prueba de unidad en el primer lugar es para 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 que deben usarse para validar un sistema antes del 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 memoria y evite usar conexiones de red de las pruebas.

1

Puede probarlos, pero no serán pruebas unitarias. La prueba de unidad 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 comprobada, etc.

Todo lo demás es prueba de integración.

La respuesta obvia de la pregunta en el título es 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 debe ser suficiente para que solo pueda escribir su código dentro de él, ni más ni menos.

0

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

Exhaustivamente probar cosas como envío de formularios, acceso a bases de datos, acceso FTP, etc. a un nivel muy detallado es a menudo simplemente una pérdida de tiempo; a menos que el software que está siendo escrita necesita un nivel muy alto de fiabilidad de las pruebas unitarias (cosas 99,999%) en exceso puede ser excesiva y un lavabo en tiempo real.

3

Prueba de la unidad de un GUI también es difícil, aunque no imposible, supongo.

+0

Existen algunas herramientas que hacen pruebas automáticas de GUI, aunque yo no he usado ninguna. – rlerallut

2

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 debe probar la unidad de cualquier cosa que toque los límites de su unidad (generalmente clase, o cualquier otra cosa que pueda ser su unidad), y burlarse 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.

2

"Lo que no debe 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.

7

El objetivo no es el 100% de cobertura de código ni es el 80% de cobertura de código. Una prueba de la unidad de ser fácil de escribir no significa que debe escribir, y una unidad de pruebas es difícil escribir no significa que usted debe evitar el esfuerzo.

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

es el costo total de la creación, mantenimiento y diagnóstico de los problemas señalados por la prueba (incluyendo los falsos positivos) vale la pena los problemas que las capturas de prueba específicos?

Si el problema es la prueba atrapa 'caro', entonces puede darse el lujo de poner esfuerzo en encontrar la manera de probarlo, y el mantenimiento de esa prueba. Si el problema de la prueba de captura es trivial entonces la escritura (y mantener!) La prueba (incluso en la presencia de cambios en el código) mejor que sea trivial.

El objetivo principal 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. También después de un cierto punto los problemas visibles para el usuario se deben a la correcta aplicación de lo equivocado que sólo puede ser atrapado por cada usuario o para las pruebas de integración.

1

No estoy de acuerdo con la respuesta de quamrana con respecto a 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.

+1

¿No deberían las pruebas de integración detectar esto? De todos modos, ¿quiénes son los proveedores de terceros? ¿No confías en ellos para probar su propio código? Los insectos se pueden pasar, pero si fallaron un error con sus pruebas, sus pruebas probablemente también lo harán. (a menos que sea piadoso o simplemente apestan) ¿Qué le está pagando a sus proveedores si tiene que hacer una regresión para probar su código? – dss539

+1

@ dss539: los proveedores externos están sujetos a las mismas presiones de desarrollo que cualquier otra persona. Si la aplicación de su línea de negocio depende de bibliotecas de terceros, ¿no cree que sería prudente migrar este riesgo mediante pruebas? –

1

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.

2

Cualquier cosa que no sea completamente determinista es un no-no para pruebas unitarias. Desea que las pruebas de su unidad SIEMPRE pasen o fallen con las mismas condiciones iniciales: si las rarezas como el enhebrado, la generación aleatoria de datos, la hora/fechas o los servicios externos pueden afectar esto, entonces no debería estar cubriéndolo 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 depender de la funcionalidad en la fecha y hora actual.

Sin embargo, 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 alto nivel, e incluso las pruebas de integración para asegurar que el sistema funciona correctamente "una vez que todo se dividió" - la cual las pruebas unitarias, por definición, No prueba.

1

FTP, SMTP, I/O, en general, deben probarse usando una interfaz. La interfaz debe implementarse mediante un adaptador (para el código real) y un simulacro para la prueba unitaria.

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

Cuestiones relacionadas