2010-04-09 12 views
23

Ok, sé que estoy haciendo una declaración así, mi pregunta es para que todos me convenzan de que estoy equivocado. Tome este escenario:¿Por qué debería molestarme con las pruebas unitarias si solo puedo usar las pruebas de integración?

Tengo el método A, que llama al método B, y están en capas diferentes.

Por lo tanto, pruebo la unidad B, que proporciona un resultado nulo. Entonces pruebo que se devuelve nulo y pasa la prueba de la unidad. Bonito.

Luego pruebo la unidad A, que espera que se devuelva una cadena vacía de B. Entonces me burlo de que la capa B está dentro, se devuelve una cadena vacía, la prueba pasa. Agradable de nuevo. (Supongamos que no me doy cuenta de la relación de A y B, o que quizás dos personas diferentes están construyendo estos métodos)

Mi preocupación es que no encontremos el problema real hasta que probemos A y B juntos, es decir Pruebas de integración. Dado que una prueba de integración proporciona cobertura sobre el área de prueba de la unidad, parece una pérdida de esfuerzo construir todas estas pruebas unitarias que realmente no nos dicen nada (o mucho) significativo.

¿Por qué estoy equivocado?

+0

Posible duplicado: http://stackoverflow.com/questions/67299/is-unit-testing-worth-the-effort – Finglas

+2

@Finglas Cambié el título de su publicación para reflejar con más precisión lo que está preguntando. En ese caso, no es un engaño. – ryeguy

+4

Las pruebas unitarias son para personas que no tienen plazos reales, horarios mal administrados, nuevos requisitos introducidos en el proyecto, hardware cambiante/defectuoso, etc., y que simplemente tienen tiempo para hacer algunas cosas, como pruebas unitarias. En el mundo real, esto no existe ... su jefe nunca le dará tiempo para hacerlo, ya que es difícil justificarlo cuantitativamente. – Toad

Respuesta

20

Aquí es an article on test categorization con algunos argumentos

no voy a mencionar los beneficios de las pruebas en su conjunto, una vez sólo estamos comparando las pruebas de unidad frente a las pruebas funcionales:

  • Prueba de la unidad le ayuda reduzca el alcance donde mirar cuando hay un error. - Incluyamos las clases C, D, E, ..., Z en este escenario. Si solo tiene una prueba de integración y falla, ¿dónde comienza a buscar? Si no tiene pruebas unitarias, , debería buscar en todas partes dentro de cada una de esas clases Y el "cableado" entre esas (que es un alcance más estrecho). Si tuviera pruebas unitarias, entonces solo necesitaría para verificar el cableado. En este caso, también sería malo no tener algunas pruebas de integración más pequeñas, como probar A, B, C y D solamente (por lo que ya sabe si el "cableado" entre esas está funcionando de hecho).
  • Con pruebas unitarias, falla más rápido. Esto es aún más cierto si tienes TDD. Probablemente escribas tus pruebas después de que creaste todas las clases A y B. Cuando realizas tu prueba, la forma en que funcionan A y B no es tan fresca en tu mente (tal vez las escribiste la semana anterior, con suerte no comiences las pruebas) solo cuando el producto está "terminado"). Entonces debes recordar lo que estabas pensando cuando los escribiste. Además, las pruebas unitarias son más rápidas, por lo que es más probable que las ejecute con más frecuencia (quizás las ejecute automáticamente cada vez que las guarde)
  • Las pruebas unitarias proporcionan una mejor documentación sobre cómo debe comportarse su clase. Si eres un "programador normal", probablemente odies escribir documentación. Esto lo obliga a escribir documentación durante la programación, y obliga a que la documentación nunca quede obsoleta (si es así, sus pruebas fallan). Y también ayuda cuando necesita cambiar el código de otra persona.

En el ideales mundo, cuando una prueba falla, usted no necesitará más de 2 minutos para saber qué buscar (sin necesidad de depuración). La idea de tener pruebas de todos los tamaños es solo una guía para lograr este objetivo, en lugar de pasar horas/días/semanas depurando =).

+4

así que en lugar de depurarlo por unas horas, pasas días y días concibiendo todas las pruebas posibles que pueden fallar o no. Además de esto, muchas cosas no son fáciles de probar. como datos de red y gui's. Entiendo que las pruebas unitarias son lo mejor de moda en el momento en que recién saliste de la escuela. Pero como dije en un comentario anterior, a veces es mejor usar ese tiempo para ser más productivo; ^) – Toad

+1

Pero con un depurador, puedo navegar a través de los métodos para ver dónde falló. Parece idealista suponer que necesito ignorar el degugger. – CodeGrue

+0

No estoy en contra de la depuración. Es necesario a veces. Pero crear una prueba unitaria para cada método en su código (de la cual el 99.9% nunca fallará) por lo que le ahorra 5 minutos la depuración es simplemente una tontería. Parece que mucha gente teme depurar. Con las herramientas actuales, nada es más fácil. – Toad

4

Las pruebas unitarias son más finas y le permite detectar errores. ¿Qué pasa si A o B fallaron? ¿Cómo sabría cuál falló si falló su prueba de integración? Y eso son solo 2 métodos: imagine si está probando la integración de un controlador frontal de una aplicación web, que carga un puñado de modelos y llama a un montón de métodos. Sería una pesadilla intentar rastrear exactamente qué salió mal.

+1

De nuevo, puedo examinar todos estos en el depurador para ver qué causó la falla. La alternativa es burlarse de las "cargas de modelos" y espero haber cubierto todos los escenarios. – CodeGrue

3

OK, las pruebas unitarias no encontrarán todos los problemas, ¡por eso también tenemos pruebas de integración!

Pero supongamos que tiene un método que debe devolver un valor entre 1 y 9 y escribe una prueba y encuentra que devuelve un valor nulo o 10, entonces sabe que el código está roto mucho antes de que llegue pruebas de integración.

+2

Esto es bueno, supongo, para los métodos que no requieren datos. En mi aplicación, menos del 1% de los métodos son de lógica pura, el resto manipula los datos. Así que el 1% de mis pruebas son pruebas unitarias ... – CodeGrue

7

Las pruebas unitarias no son para probar lo que debe probarse en integración: son conjuntos complementarios de pruebas. Las pruebas unitarias garantizan que una determinada unidad del código por sí sola realiza lo que fue diseñado para hacer, nada más. Las pruebas de integración se aseguran de que todas sus unidades funcionen bien juntas para cumplir con los requisitos generales.

+0

+1 Si su ejemplo de prueba de integración * pasó *, nunca sabría que A o B * * no están entregando los resultados esperados. – LesterDove

+1

Mi argumento es que las pruebas de integración también captan el funcionamiento de las unidades. – CodeGrue

+0

@CodeGrue - puede o no puede.De todos modos, si no ve ningún valor en las pruebas unitarias, simplemente déjelo en paz. Si funciona, genial. Nadie dice que las pruebas unitarias * son * necesarias para que un sistema funcione, solo que pueden brindarle una mejor posibilidad de que suceda. –

4

creo que las principales razones son:

1: pruebas de nivel de unidad de darle más información sobre lo que está fallando.

2: no puede ejecutar pruebas de integración hasta que sus componentes estén integrados. Cuanto antes encuentre un error, más fácil/más barato será solucionarlo.

3

Estoy de acuerdo con usted en que en su caso simple, no hay necesidad de pruebas unitarias. Las pruebas (unidad, integración, funcional, regresión) dependen del tamaño de su proyecto y del número de personas involucradas y del nivel de experiencia de todos los involucrados.

Como aumenta cualquiera de estos factores (bueno, el último debería disminuir), la necesidad de realizar pruebas aumenta. Debe encontrar una solución que sea apropiada y aplicable a su proyecto en particular.

Soy un gran admirador de las pruebas unitarias y creo que todos los desarrolladores deberían escribirlas y automatizarlas independientemente del tamaño del proyecto. Se asegurarán de que su código esté libre de errores y realmente lo ayudará cuando regrese al proyecto después de varios meses.

También creo que como hay varias personas trabajando en el proyecto durante un período prolongado (lea cualquier cosa que no sea un proyecto descartable), entonces también necesita pruebas de integración automatizadas para garantizar que los diversos componentes funcionen juntos.

1

La mayor parte del problema está en el escenario que ha planteado: de acuerdo con su descripción, todos B hace es devolver nulo. La unidad que prueba algo trivial probablemente no tenga sentido, pero para empezar es escribir el código. Si todo lo que necesita es un nulo, use null directamente y elimine B por completo. Si B justifica su existencia haciendo realmente algo más que devolver nulo, entonces la prueba de unidad que ha descrito está incompleta, y necesita probar lo que se supone que B debe hacer.

+0

La suposición es que B hace un montón de trabajo para determinar que nula es la respuesta adecuada. – CodeGrue

+0

@CodeGrue: en ese caso, debe probarlo correctamente haciendo todo el trabajo. –

0

Si A es una consulta que se ejecuta durante 2 horas y prepara datos para B, que es otra consulta que se ejecuta durante 2 horas, ¿por qué debo esperar 4 horas para encontrar un problema cuando puedo esperar 2? No es como si esta fuera una idea nueva. ¿Crees que las compañías de automóviles montan todo el automóvil antes de ver si el motor funciona?

+0

Pero en mi caso, lo probaría durante 2 horas, luego probaría otras 2 horas, luego no encontraría que había un problema hasta que las pruebas otras 4 horas. – CodeGrue

+0

Con la prueba unitaria, ejecuta el módulo A (2 horas), soluciona el problema, vuelve a ejecutar el módulo A (2 horas), ejecuta el módulo B (2 horas), monta, ejecuta todo (4 horas). Entonces tiene un total de 10 horas, frente a 8 sin pruebas unitarias. Entonces las pruebas unitarias apenas agregan ese tiempo. Pero no hay nada de mágico en las 2 horas que elegí. A medida que B se hace más largo, se pone mejor. – brydgesk

+0

Sin mencionar que está asignando tiempo cero para solucionar el problema. Ciertamente, tomará menos tiempo solucionar un problema encontrado en una prueba unitaria que uno encontrado en una prueba de integración. –

2

Otra razón por la que no he visto a nadie más dirección: No siempre será usted quien mantendrá el código que escribe. Asumamos que he escrito una & B en módulos separados, de modo que cada uno es en un frasco separado & tiene su propio archivo experta en construcción. Supongamos además que A es un método Dao y B es una especie de capa de Servicio. Si he escrito incluso una prueba de unidad básica para mi Dao (¡quizás usando desarrollo impulsado por prueba, incluso!), Tengo mucha más confianza de que los cambios futuros en la estructura de la base de datos & que puedan afectar mi dao se detectan temprano. Si, por ejemplo, en mi equipo, otro desarrollador necesita agregar columnas a una tabla de base de datos que utiliza mi dao, ciertamente quiero que sepan de inmediato si al hacerlo se romperán mis métodos de dao. Si tienen que esperar para construir todas las capas & ejecute una prueba de integración para verificar que, en mi opinión, están desperdiciando un tiempo de desarrollo precioso. Como desarrollador, preferiría ejecutar 10 segundos de prueba unitaria 10 veces para reparar & poner a prueba cualquier interrupción que encuentre que ejecutar una integración de 2 minutos & prueba de integración ejecutar varias veces. Obviamente, los tiempos varían mucho según el tamaño del proyecto (y su hardware), pero ese es el tipo de veces que estoy lidiando en mi proyecto actual.

2

Las pruebas de unidad no se tratan de la depuración durante el desarrollo inicial. Se trata de diseño, y se trata de adaptarse al cambio. Las pruebas de mi unidad casi nunca me dicen dónde está el error cuando estoy en mi primer paso por un trozo de código. Mis pruebas me advierten cuando surge un error seis meses después porque alguien (posiblemente yo mismo) modificó un objeto cuyas relaciones no entendieron del todo.

Decir pruebas unitarias son una pérdida de tiempo durante develoment inicial es como quejarse de que mi coche se millaje de mierda en su salida de la entrada de mi casa.

2

refuerzo (con suerte) después de Samuel Carrijo ...


Al elegir entre: 1) pruebas de unidad y una pequeña prueba de integración vs 2) sólo la prueba de integración que están haciendo un calcularon apuesta. Si el componente integrado es complejo, cualquier falla en la prueba de integración será difícil de encontrar sin pruebas unitarias. A veces me equivoco, obtengo un error de prueba en la prueba de integración y comienzo a escribir las pruebas unitarias sin intentar depurar. Si apuesta por no necesitar pruebas unitarias y gana, puede ahorrarse una buena cantidad de tiempo, y aún así tener confianza en su código, pero no obtiene los beneficios de "especificación" que proporcionan las pruebas unitarias al siguiente tipo que tiene que tocar tu código.

1

Las pruebas de integración adolecen de una forma de combinatorial explosion: el método Say A tiene 5 maneras diferentes de comportarse (diferentes casos extremos, etc.), y también el método B. Si las prueba juntas, ahora hay en teoría 25 diferentes casos que tienes que probar! Sí, muchos de ellos pueden terminar siendo los mismos, o no pueden ocurrir por una razón u otra, pero básicamente, mientras más cosas se prueban juntas, más imposible se vuelve probar todos los casos extremos.

Cuestiones relacionadas