¿Cuál es la diferencia entre pruebas unitarias, funcionales, de aceptación e integración? [cerrado]

799

¿Cuál es la diferencia entre pruebas unitarias, funcionales, de aceptación e integración (y cualquier otro tipo de pruebas que no mencioné)?

Andrés
fuente
1
Ver también sqa.stackexchange.com/a/23396/8992
Michael Durrant
1
¡Creo que olvidó incluir pruebas de carga!
Hablar es barato Muéstrame el código

Respuestas:

1350

Dependiendo de dónde mire, obtendrá respuestas ligeramente diferentes. He leído mucho sobre el tema, y ​​aquí está mi destilación; Una vez más, estos son ligeramente lanudos y otros pueden estar en desacuerdo.

Pruebas unitarias

Prueba la unidad de funcionalidad más pequeña, generalmente un método / función (por ejemplo, dada una clase con un estado particular, llamar al método x en la clase debería hacer que y suceda). Las pruebas unitarias deben centrarse en una característica particular (por ejemplo, llamar al método pop cuando la pila está vacía debe arrojar un InvalidOperationException). Todo lo que toca debe hacerse en la memoria; Esto significa que el código de prueba y el código bajo prueba no deberían:

  • Llamar a colaboradores (no triviales)
  • Acceder a la red
  • Golpear una base de datos
  • Usa el sistema de archivos
  • Gira un hilo
  • etc.

Cualquier tipo de dependencia que sea lenta / difícil de entender / inicializar / manipular se debe tropezar / burlar / usar usando las técnicas apropiadas para que pueda centrarse en lo que está haciendo la unidad de código, no en lo que hacen sus dependencias.

En resumen, las pruebas unitarias son lo más simples posible, fáciles de depurar, confiables (debido a factores externos reducidos), rápidas de ejecutar y ayudan a probar que los bloques de construcción más pequeños de su programa funcionan según lo previsto antes de que se junten. La advertencia es que, aunque puede probar que funcionan perfectamente de forma aislada, las unidades de código pueden explotar cuando se combinan, lo que nos lleva a ...

Pruebas de integración

Las pruebas de integración se basan en pruebas unitarias combinando las unidades de código y comprobando que la combinación resultante funciona correctamente. Puede ser el interior de un sistema o combinar varios sistemas para hacer algo útil. Además, otra cosa que diferencia las pruebas de integración de las pruebas unitarias es el entorno. Las pruebas de integración pueden y utilizarán subprocesos, acceder a la base de datos o hacer lo que sea necesario para garantizar que todo el código y los diferentes cambios del entorno funcionen correctamente.

Si ha creado un código de serialización y la unidad ha probado sus entrañas sin tocar el disco, ¿cómo sabe que funcionará cuando esté cargando y guardando en el disco? Tal vez se olvidó de vaciar y deshacerse de los archivos. Tal vez los permisos de sus archivos son incorrectos y ha probado las entrañas utilizando flujos de memoria. La única forma de averiguarlo con certeza es probarlo 'de verdad' utilizando un entorno más cercano a la producción.

La principal ventaja es que encontrarán errores que las pruebas unitarias no pueden, como errores de cableado (por ejemplo, una instancia de clase A recibe inesperadamente una instancia nula de B) y errores de entorno (funciona bien en mi máquina con una sola CPU, pero mi la máquina de 4 núcleos de un colega no puede pasar las pruebas). La principal desventaja es que las pruebas de integración tocan más código, son menos confiables, las fallas son más difíciles de diagnosticar y las pruebas son más difíciles de mantener.

Además, las pruebas de integración no necesariamente prueban que una característica completa funcione. Puede que el usuario no se preocupe por los detalles internos de mis programas, ¡pero a mí sí!

Pruebas Funcionales

Las pruebas funcionales verifican la corrección de una característica particular comparando los resultados de una entrada dada con la especificación. Las pruebas funcionales no se refieren a resultados intermedios o efectos secundarios, solo al resultado (no les importa que después de hacer x, el objeto y tenga el estado z). Se escriben para probar parte de la especificación, como "llamar a la función Square (x) con el argumento de 2 devuelve 4".

Prueba de aceptacion

Las pruebas de aceptación parecen dividirse en dos tipos:

La prueba de aceptación estándar implica realizar pruebas en todo el sistema (por ejemplo, usar su página web a través de un navegador web) para ver si la funcionalidad de la aplicación cumple con la especificación. Por ejemplo, "al hacer clic en un ícono de zoom debería agrandar la vista del documento en un 25%". No existe un continuo real de resultados, solo un resultado aprobado o no aprobado.

La ventaja es que las pruebas se describen en un inglés sencillo y garantiza que el software, en su conjunto, esté completo. La desventaja es que has subido otro nivel en la pirámide de prueba. Las pruebas de aceptación tocan montañas de código, por lo que rastrear una falla puede ser complicado.

Además, en el desarrollo ágil de software, las pruebas de aceptación del usuario implican crear pruebas para reflejar las historias de usuarios creadas por / para el cliente del software durante el desarrollo. Si pasan las pruebas, significa que el software debe cumplir con los requisitos del cliente y las historias pueden considerarse completas. Un conjunto de pruebas de aceptación es básicamente una especificación ejecutable escrita en un lenguaje específico de dominio que describe las pruebas en el lenguaje utilizado por los usuarios del sistema.

Conclusión

Todos son complementarios. A veces es ventajoso enfocarse en un tipo o evitarlos por completo. La principal diferencia para mí es que algunas de las pruebas analizan las cosas desde la perspectiva de un programador, mientras que otras utilizan un enfoque en el cliente / usuario final.

Mark Simpson
fuente
19
+1. @ Mark Simpson ¿Podrían resumirse las pruebas funcionales y de aceptación como "pruebas del sistema"? ¿Dónde encajan las pruebas de extremo a extremo? (vocabulario demasiado diferente para mi gusto)
Torsten Engelbrecht
3
@Franz Estaba hablando de la capacidad y facilidad con la que puede reducir el riesgo aislando unidades de código y probándolas. Sin embargo, tienes razón, el lenguaje que utilicé era un poco flojo, ya que las pruebas no pueden probar que el código esté libre de errores.
Mark Simpson
15
A pesar de los votos positivos, esto está completamente mal. Las pruebas unitarias no prueban incluso a los colaboradores "triviales"; cualquier dependencia inyectada debe ser burlada. Las pruebas funcionales no prueban el "comportamiento"; solo prueban "función", es decir, "f (A) devuelve B". Si los efectos secundarios son importantes, es "conductual". Si estos incluyen llamadas al sistema, también son pruebas de "sistema", como en "pruebas de sistema de comportamiento". (Ver testerab @ a continuación.) Las pruebas de "aceptación" son un subconjunto de "pruebas del sistema de comportamiento" que cubren la pila completa. La "integración" prueba hacia arriba, simulando el uso real; prueba que todas las dependencias se pueden integrar en la práctica.
cdunn2001
77
@ cdunn2001: No se preocupe, la crítica constructiva siempre es buena :) Su comentario me enseñó algunas cosas que no sabía y limpió un poco mi terminología. Siempre estoy interesado en aprender cosas nuevas de los desarrolladores que están interesados ​​en las pruebas. Recuerdo la primera vez que descubrí el blog de Miško Hevery: era como un tesoro :)
Mark Simpson
11
@ MarkSimpson, aunque su respuesta es muy buena, me gustaría un poco más de detalles con respecto a las pruebas funcionales. Quiero decir, en su respuesta, para mí, es difícil distinguir entre las pruebas funcionales y las pruebas unitarias. Espero que tengas tiempo para esto, ¡sigue con el gran trabajo!
Andrei Sandulescu
90

Lo importante es que sepa qué significan esos términos para sus colegas. Los diferentes grupos tendrán definiciones ligeramente diferentes de lo que significan cuando digan pruebas "completas de principio a fin", por ejemplo.

Recientemente me encontré con el sistema de nombres de Google para sus pruebas, y más bien me gusta: omiten los argumentos simplemente usando Small, Medium y Large. Para decidir en qué categoría se ajusta una prueba, analizan algunos factores: cuánto tiempo lleva ejecutar, accede a la red, la base de datos, el sistema de archivos, los sistemas externos, etc.

http://googletesting.blogspot.com/2010/12/test-sizes.html

Me imagino que la diferencia entre Pequeño, Mediano y Grande para su lugar de trabajo actual podría variar de la de Google.

Sin embargo, no se trata solo del alcance, sino también del propósito. El punto de Mark sobre las diferentes perspectivas para las pruebas, por ejemplo, programador vs cliente / usuario final, es realmente importante.

testerab
fuente
66
+1 para el nombre de prueba de google, ya que ayuda a dar un poco de perspectiva sobre por qué varias organizaciones / personas tienen diferentes definiciones para las pruebas.
Mark Simpson,
Este también es un artículo muy bueno que explica por qué usaría diferentes niveles de prueba y qué obtiene de ellos: kentcdodds.com/blog/unit-vs-integration-vs-e2e-tests
testerab
63

http://martinfowler.com/articles/microservice-testing/

La publicación del blog de Martin Fowler habla sobre estrategias para probar el código (especialmente en una arquitectura de microservicios), pero la mayor parte se aplica a cualquier aplicación.

Citaré su resumen de diapositivas:

  • Pruebas unitarias: ejercite las piezas más pequeñas de software comprobable en la aplicación para determinar si se comportan como se esperaba.
  • Pruebas de integración: verifique las rutas de comunicación y las interacciones entre los componentes para detectar defectos en la interfaz.
  • Pruebas de componentes: limite el alcance del software ejercido a una parte del sistema bajo prueba, manipulando el sistema a través de interfaces de código interno y utilizando dobles de prueba para aislar el código bajo prueba de otros componentes.
  • Pruebas de contrato: verifique las interacciones en el límite de un servicio externo afirmando que cumple con el contrato esperado por un servicio consumidor.
  • Pruebas de extremo a extremo: verifique que un sistema cumpla con los requisitos externos y logre sus objetivos, probando todo el sistema de principio a fin.
Máxima
fuente
Ese es un gran artículo por cierto. Sin embargo, no entiendo completamente para qué son las pruebas de contrato. ¿No son redundantes a la luz de las pruebas de componentes e integración?
wheleph
En algunos idiomas (que utiliza Mr Fowler) puede implementar una interfaz que no esté expuesta al usar la definición estándar de una clase, por ejemplo, void IMyInterface.MyMethod (). Que a su vez lógicamente tendría sus propias pruebas. Aunque en ese momento te diriges hacia BDD. Irónicamente, el Sr. Fowler también ha tenido un acaparamiento de tierras.
Skarsnik
2
No es el artículo de Fowler por cierto, recién publicado allí. Las pruebas de contrato son pruebas que se realizan después de que los clientes comienzan a usar su servicio, luego escribe pruebas que verifican si no rompió algo para ese cliente en particular, es decir, cambiar la API del servicio.
Rafał Łużyński
Las pruebas de unidad, integración y componentes de @wheleph hablan principalmente de los componentes internos del software que son altamente controlables por el desarrollador. Un problema en los primeros tres significa cambiar su fuente para solucionar el problema. - Las pruebas de contrato tocan lo que se le prometió en cuanto a funcionalidad, pero es posible que no pueda cambiar directamente en caso de defecto. Esto requiere agregar un código de soporte para solucionar esos posibles problemas en lugar de solo solucionar el defecto. - Por lo tanto, trabajaría en torno a un servicio web que le devolvería json malformados incluso si la especificación del contrato le indicara que es de una determinada estructura.
Yemi Bedu
31

Prueba de unidad : como su nombre indica, este método prueba a nivel de objeto. Los componentes de software individuales se prueban para detectar cualquier error. El conocimiento del programa es necesario para esta prueba y los códigos de prueba se crean para verificar si el software se comporta como debería.

Pruebas funcionales : se llevan a cabo sin ningún conocimiento del funcionamiento interno del sistema. El probador intentará usar el sistema simplemente siguiendo los requisitos, proporcionando diferentes entradas y probando las salidas generadas. Esta prueba también se conoce como prueba de caja cerrada o caja negra.

Prueba de aceptación : esta es la última prueba que se realiza antes de que el software se entregue al cliente. Se lleva a cabo para garantizar que el software desarrollado cumpla con todos los requisitos del cliente. Existen dos tipos de pruebas de aceptación: una realizada por los miembros del equipo de desarrollo, conocida como prueba de aceptación interna (prueba alfa), y la otra realizada por el cliente o usuario final conocido como (prueba beta)

Pruebas de integración : los módulos individuales que ya están sujetos a pruebas unitarias se integran entre sí. Generalmente se siguen los dos enfoques:

1) De arriba hacia abajo
2) De abajo hacia arriba

Cha
fuente
¿Qué quieres decir con de arriba abajo y de abajo hacia arriba? ¿Las pruebas de integración son lo mismo que las pruebas de extremo a extremo?
tamj0rd2
18

Esto es muy simple.

  1. Prueba unitaria: esta es la prueba que realmente realizan los desarrolladores que tienen conocimientos de codificación. Esta prueba se realiza en la fase de codificación y es parte de la prueba de caja blanca. Cuando un software viene para desarrollo, se desarrolla en el fragmento de código o segmentos de código conocidos como una unidad. Y las pruebas individuales de estas unidades se denominan pruebas unitarias realizadas por los desarrolladores para descubrir algún tipo de error humano, como la falta de cobertura de la declaración, etc.

  2. Pruebas funcionales: esta prueba se realiza en la fase de prueba (QA) y es parte de la prueba de caja negra. La ejecución real de los casos de prueba previamente escritos. Esta prueba es realizada por probadores, encuentran el resultado real de cualquier funcionalidad en el sitio y comparan este resultado con el resultado esperado. Si encontraron alguna disparidad, entonces esto es un error.

  3. Prueba de aceptación: conocida como UAT. Y esto en realidad lo hacen el probador, los desarrolladores, el equipo de gestión, el autor, los escritores y todos los que participan en este proyecto. Para garantizar que el proyecto finalmente esté listo para ser entregado sin errores.

  4. Pruebas de integración: las unidades de código (explicadas en el punto 1) se integran entre sí para completar el proyecto. Estas unidades de códigos pueden estar escritas en diferentes tecnologías de codificación o pueden tener versiones diferentes, por lo que esta prueba la realizan los desarrolladores para garantizar que todas las unidades del código sean compatibles con otras y que no haya ningún problema de integración.

Rakesh Kumar
fuente
1
@OlegTsyba la respuesta llegó 4 años después de que se respondiera la pregunta.
bentesha
1
Nunca debemos comenzar una respuesta con "Esto es muy simple", especialmente si se trata de un tema complejo como este.
milosmns
6

Algunas ideas (relativamente) recientes contra la burla excesiva y las pruebas unitarias puras:

cdunn2001
fuente
Soy nuevo en probar código. Las pruebas unitarias parecen en su mayoría una pérdida de tiempo. Pensé que estaba haciendo pruebas unitarias pero estaba haciendo pruebas de integración y luego leí sobre pruebas unitarias y parece una tontería, ¿tal vez para personas con muy poca experiencia? Existe la posibilidad de que me esté perdiendo algún tipo de punto.
PixMach
Si la Unidad se define de manera amplia, entonces está realizando pruebas de unidad correctamente. Me opongo a probar los detalles de implementación. Una clase privada no debe ser "probada por unidad". Sin embargo, si tiene varias clases públicas, puede verse tentado a burlarse de una mientras prueba otra. Ese es el verdadero debate. ¿Es la Unidad (a) toda su biblioteca? (b) cada clase pública dentro de la biblioteca? O (c), cada método público dentro de cada clase? Prefiero probar una biblioteca determinada como un componente integrado, pero simular o falsificar dependencias externas (a menos que sean rápidas y confiables). Entonces creo que estoy contigo.
cdunn2001
1
@PixMach: en realidad es al revés. No tener (buenas) pruebas unitarias en su lugar, desperdicia mucho tiempo, si usted (o alguien más) tiene que cambiar ese código en el futuro. Si tiene experiencia en el mantenimiento de código con y sin pruebas unitarias, sabrá la diferencia. La idea es que si se rompe una prueba unitaria, debe saber exactamente qué parte del código debe repararse. Las pruebas de aceptación / integración a gran escala que fallan a menudo solo le dicen: no funciona. Y luego debe comenzar la depuración de la vieja escuela ...
Goodsquirrel
@Buena ardilla, depende de lo que llames una "unidad". Ese es el problema. Las pruebas malas se eliminarán durante la refactorización. Las buenas pruebas seguirán siendo útiles. Las malas pruebas no agregan valor y se interponen en el camino. Las buenas pruebas se documentan por sí mismas y son muy apreciadas. Seamos específicos. Tengo un método privado para devolver un valor si otro valor es True, de lo contrario, es un valor predeterminado. (Código heredado). ¿Debería probarse ese método? Yo digo que no. Otro método privado devuelve el enésimo número de Fibonacci. ¿Debería eso ser probado? Yo digo si.
cdunn2001
1
El código expuesto más pequeño . Gran diferencia.
cdunn2001
5

Te explicaré esto con un ejemplo práctico y sin teorías:

Un desarrollador escribe el código. No hay GUI implementada todavía. Las pruebas en este nivel verifican que las funciones funcionan correctamente y que los tipos de datos son correctos. Esta fase de prueba se llama prueba unitaria.

Cuando se desarrolla una GUI y la aplicación se asigna a un probador, este verifica los requisitos comerciales con un cliente y ejecuta los diferentes escenarios. Esto se llama prueba funcional. Aquí estamos mapeando los requisitos del cliente con los flujos de aplicaciones.

Pruebas de integración: supongamos que nuestra aplicación tiene dos módulos: RRHH y Finanzas. El módulo de recursos humanos fue entregado y probado previamente. Ahora Finance está desarrollado y está disponible para probar. Las funciones interdependientes también están disponibles ahora, por lo que en esta fase, probará los puntos de comunicación entre los dos y verificará que funcionan según lo solicitado en los requisitos.

La prueba de regresión es otra fase importante, que se realiza después de cualquier nuevo desarrollo o corrección de errores. Su objetivo es verificar previamente las funciones de trabajo.

fahad shaikh
fuente
1
"Un desarrollador escribe el código. Aún no se ha implementado GUI. La prueba en este nivel verifica que las funciones funcionan correctamente y los tipos de datos son correctos. Esta fase de prueba se llama Prueba unitaria" Esto no es cierto. GUI es en realidad solo un "complemento". Ya puede escribir pruebas E2E en su salida API. (o cualquier objeto de respuesta que genere)
usuario3790897
4

prueba unitaria: se sabe que la prueba de módulo individual o componente independiente en una aplicación es prueba unitaria, la prueba unitaria será realizada por el desarrollador.

Prueba de integración: combinando todos los módulos y probando la aplicación para verificar que la comunicación y el flujo de datos entre los módulos funcionan correctamente o no, esta prueba también la realizan los desarrolladores.

la prueba funcional que verifica la funcionalidad individual de una aplicación es una prueba funcional

prueba de aceptación esta prueba la realiza el usuario final o el cliente si la aplicación de compilación cumple con los requisitos del cliente y las especificaciones del cliente se conocen como pruebas de aceptación

malini
fuente