unit-testing - software - pruebas unitarias java
¿Por qué usar pruebas de integración en lugar de pruebas unitarias es una mala idea? (12)
Creo que la cobertura es el problema principal.
Se supone que una prueba de unidad de un componente pequeño específico, como un método o, a lo sumo, una clase debe probar ese componente en cada escenario legal (por supuesto, uno resume las clases de equivalencia, pero cada una de las principales debe estar cubierta). Como resultado, un cambio que rompe la especificación establecida debe ser atrapado en este punto.
En la mayoría de los casos, una integración usa solo un subconjunto de los escenarios posibles para cada subunidad, por lo que es posible que las unidades que funcionan mal todavía produzcan un programa que inicialmente se integre bien.
Por lo general, es difícil lograr la máxima cobertura en las pruebas de integración por todas las razones que especificó a continuación. Sin las pruebas de unidad, es más probable que un cambio en una unidad que esencialmente lo opera en un nuevo escenario no se detecte y se pierda en las pruebas de integración. Incluso si no se pasa por alto, localizar el problema puede ser extremadamente difícil.
No estoy seguro de que la mayoría de los desarrolladores se refieran a las pruebas unitarias como pruebas de integración. Mi impresión es que la mayoría de los desarrolladores entienden las diferencias, lo que no significa que ellos también practiquen.
Permítanme comenzar desde la definición:
Unit Test es un método de verificación y validación de software en el que un programador prueba si las unidades individuales del código fuente son aptas para el uso.
La prueba de integración es la actividad de la prueba de software en la cual los módulos de software individuales se combinan y se prueban en grupo.
A pesar de que tienen propósitos diferentes, muy a menudo estos términos se mezclan. Los desarrolladores se refieren a las pruebas de integración automatizadas como pruebas unitarias. También algunos argumentan cuál es mejor, lo que me parece una pregunta errónea.
Me gustaría pedirle a la comunidad de desarrollo que comparta sus opiniones sobre por qué las pruebas de integración automatizada no pueden reemplazar las pruebas unitarias clásicas .
Aquí están mis propias observaciones:
- Las pruebas de integración no se pueden utilizar con el enfoque TDD
- Las pruebas de integración son lentas y no se pueden ejecutar muy a menudo.
- En la mayoría de los casos, las pruebas de integración no indican la fuente del problema
- Es más difícil crear un entorno de prueba con pruebas de integración
- es más difícil asegurar una alta cobertura (por ejemplo, simular casos especiales, fallas inesperadas, etc.)
- Las pruebas de integración no se pueden utilizar con pruebas basadas en interacción
- Las pruebas de integración mueven el momento del descubrimiento del defecto más allá (desde paxdiablo )
EDIT: Solo para aclarar una vez más: la pregunta no es si usar la integración o las pruebas unitarias y no sobre cuál es más útil. Básicamente, quiero recopilar argumentos para los equipos de desarrollo que escriben SOLAMENTE pruebas de integración y las consideran como pruebas unitarias. Cualquier prueba que involucre componentes de diferentes capas se considera como prueba de integración. Esto es para comparar con la prueba de unidad donde el aislamiento es el objetivo principal.
Gracias andrey
En muchos casos necesitas ambos. Sus observaciones van por buen camino en lo que a mí respecta con respecto al uso de las pruebas de integración como pruebas unitarias, pero no significa que las pruebas de integración no sean valiosas o necesarias, solo que tienen un propósito diferente. Se podría argumentar igualmente que las pruebas unitarias no pueden reemplazar las pruebas de integración, precisamente porque eliminan las dependencias entre objetos y no ejercitan el entorno real. Ambos son correctos.
Encuentro pruebas de integración notablemente superiores a las pruebas unitarias. Si hago una prueba unitaria de mi código, solo estoy probando lo que hace en comparación con mi comprensión de lo que debería hacer. Eso solo atrapa errores de implementación. Pero a menudo un problema mucho más grande son los errores de comprensión. Las pruebas de integración captan ambas.
Además, hay una diferencia de costo dramática; Si está haciendo un uso intensivo de las pruebas unitarias, no es raro que superen todo el resto de su código. Y deben mantenerse, al igual que el resto del código. Las pruebas de integración son mucho más baratas y, en la mayoría de los casos, ya las necesita de todos modos.
Hay casos raros en los que podría ser necesario usar pruebas unitarias, por ejemplo, para las rutas de manejo de errores internos que no pueden activarse si el resto del sistema funciona correctamente, pero la mayoría de las veces las pruebas de integración solo dan mejores resultados para lejos costo más bajo.
Ha habido estudios (a) que muestran que el costo de corregir un error aumenta a medida que se aleja del punto en el que se introdujo el error.
Por ejemplo, generalmente le costará relativamente poco corregir un error en un software que aún no ha incorporado al control de código fuente. Es su momento y no mucho, lo justificaría (suponiendo que usted sea bueno en su trabajo).
Compare esto con cuánto cuesta arreglarlo cuando el cliente (o todos sus clientes) encuentran ese problema. Muchos niveles de personas se involucran y el nuevo software debe construirse rápidamente y ser expulsado al campo.
Esa es la comparación extrema. Pero incluso la diferencia entre las pruebas de unidad e integración puede ser evidente. El código que falla la prueba de la unidad afecta principalmente solo al único desarrollador (a menos que otros desarrolladores / probadores / etc lo estén esperando, por supuesto). Sin embargo, una vez que su código se involucra en las pruebas de integración, un defecto puede comenzar a detener a otras personas en su equipo.
No soñaríamos con reemplazar nuestras pruebas de unidad con pruebas de integración ya que:
- Nuestras pruebas unitarias también están automatizadas, por lo que, aparte de la configuración inicial, el costo de su ejecución es pequeño.
- Forman el inicio de las pruebas de integración. Todas las pruebas unitarias se vuelven a ejecutar en la fase de integración para verificar que la integración en sí no haya roto nada, y luego están las pruebas adicionales que el equipo de integración ha agregado.
(a) Consulte, por ejemplo, http://slideshare.net/Vamsipothuri/defect-prevention , diapositiva # 5, o busque en la red la Defect prevention : Reducing costs and enhancing quality
.
Las pruebas de integración generalmente ocurren después de las pruebas unitarias. No estoy seguro de qué valor hay en las interacciones de prueba entre unidades que no se han probado.
No tiene sentido probar cómo los engranajes de una máquina giran juntos si los engranajes se rompen.
Las pruebas de integración le permiten verificar que todos los casos de uso de su aplicación funcionan.
Las pruebas unitarias verifican que la lógica de bajo nivel en su aplicación sea correcta.
Las pruebas de integración son más útiles para que los gerentes se sientan más seguros sobre el estado del proyecto (¡pero también son útiles para los desarrolladores!).
Las pruebas unitarias son más útiles para los desarrolladores que escriben y cambian la lógica de la aplicación.
Y, por supuesto, úsalos para obtener los mejores resultados.
Las pruebas de integración te dicen si está funcionando. Las pruebas unitarias te dicen lo que no funciona. Mientras todo funcione, "no necesita" las pruebas de unidad, pero una vez que algo está mal, es muy agradable que la prueba de unidad lo señale directamente al problema. Como dices, sirven para diferentes propósitos; Es bueno tener ambos.
Para abordar directamente su tema: las pruebas de integración no son un problema, no son el problema. Usarlos en lugar de pruebas unitarias es.
Los dos tipos de pruebas son diferentes. Las pruebas unitarias, en mi opinión, no son una alternativa a las pruebas de integración. Principalmente porque las pruebas de integración suelen ser específicas del contexto. Es posible que tenga un escenario en el que una prueba de unidad falla y su integración no, y viceversa. Si implementa una lógica de negocios incorrecta en una clase que utiliza muchos otros componentes, desearía que sus pruebas de integración resaltaran estas, las pruebas unitarias no tienen en cuenta esto. Entiendo que las pruebas de integración son rápidas y fáciles. Yo diría que confía en sus pruebas de unidad cada vez que realice un cambio en su base de código y tener una lista de verdes le dará más confianza de que no ha roto ningún comportamiento esperado a nivel de clase individual. Las pruebas unitarias que le dan una prueba contra una sola clase hacen lo que fue diseñado para hacer. Las pruebas de integración prueban que varias clases que trabajan juntas hacen lo que usted espera que hagan para esa instancia de colaboración en particular. Esa es toda la idea del desarrollo de OO: clases individuales que encapsulan lógica particular, lo que permite su reutilización.
Se escribe una prueba de unidad para probar un método en una clase. Si esa clase depende de cualquier tipo de recurso o comportamiento externo, debe burlarse de ellos, para asegurarse de que solo evalúa su clase. No debe haber recursos externos en una prueba de unidad.
Una prueba de integración es un nivel más alto de granularidad y, como dijo, debe probar varios componentes para verificar si funcionan juntos como se espera. Necesitas pruebas de integración y pruebas unitarias para la mayoría de los proyectos. Pero es importante que se mantengan separados y se entienda la diferencia.
Las pruebas unitarias, en mi opinión, son más difíciles de entender para las personas. Requiere un buen conocimiento de los principios de OO (basado fundamentalmente en una responsabilidad de clase uno). Si puede probar todas sus clases de forma aislada, es probable que tenga una solución de diseño de pozo que sea mantenible, flexible y ampliable.
- Cuando realiza el check-in, su servidor de compilación solo debe ejecutar pruebas unitarias y deben realizarse en unos segundos, no minutos u horas.
- Las pruebas de integración deben ejecutarse durante la noche o manualmente, según sea necesario.
Se trata de reducir el tiempo de iteración.
Con las pruebas unitarias, puede escribir una línea de código y verificarlo en aproximadamente un minuto. Con las pruebas de integración, generalmente toma mucho más tiempo (y el costo aumenta a medida que el proyecto crece).
Ambos son claramente útiles, ya que ambos detectarán problemas que el otro no puede detectar.
OTOH, desde un enfoque TDD "puro", las pruebas unitarias no son pruebas , son especificaciones de funcionalidad. Las pruebas de integración, OTOH, realmente hacen "pruebas" en el sentido más tradicional de la palabra.
- Las pruebas de integración son lentas.
- Las pruebas de integración pueden romper diferentes razones (no está enfocada y aislada). Por lo tanto, necesita más depuración en fallas.
- La combinación de escenarios es demasiado grande para la prueba de integración cuando no se prueba por unidad.
Principalmente hago pruebas unitarias y 10 veces menos pruebas de integración (configuración, consultas).
- Las pruebas unitarias se enfocan en probar un componente individual y no dependen de dependencias externas. Se utilizan comúnmente con mocks o talones.
- Las pruebas de integración involucran múltiples componentes y pueden depender de dependencias externas.
Creo que ambos son valiosos y ninguno puede reemplazar al otro en el trabajo que hacen. Veo muchas pruebas de integración enmascaradas como pruebas unitarias a pesar de tener dependencias y tardar mucho tiempo en ejecutarse. Deben funcionar por separado y como parte de un sistema de integración continua.
Las pruebas de integración a menudo encuentran cosas que las pruebas unitarias no hacen ...