La intención de esta nota es acercar una definición para cada uno de estos términos para así poder entender las diferencias entre ellos y el por qué no debería excluirse ninguno de los niveles en las pruebas de un producto software.
Pruebas unitarias: para realizar un prueba unitaria lo primero que deberíamos definir es cuál es el alcance de nuestra unidad, a qué grado de granularidad queremos llegar y esto debe tener en cuenta la tecnología y lenguajes sobre los que estamos trabajando. Hoy en día el paradigma de objetos se encuentra extendido a muchos negocios y lenguajes de programación como Java, .Net, Ruby, PHP, C++, etc., que hacen uso de dicho paradigma, resultan la elección adecuada para modelar y diseñar nuestros sistemas. Sin embargo hay todavía vetustos sistemas que hacen uso de lenguajes que aplican paradigmas distintos como por ejemplo Report Program Generator (RPG) y COmmon Business-Oriented Language (COBOL ) que, por distintas cuestiones, muchas de ellas económicas, integran y conviven con plataformas más modernas. Esta cuestión hace que muchas veces no podamos definir de forma taxativa el criterio de unidad para nuestras pruebas ya que la tecnología aplicada, los lenguajes de programación forman parte de ella, influyen en gran medida en el significado de unidad. Para dar un ejemplo sencillo, si nuestro sistema estuviese diseñado en un lenguaje orientado a objetos podríamos decir sin temor a equivocarnos que nuestra unidad más pequeña podría ser una clase y así definir si quisiéramos, que ese es el nivel de granularidad que elegimos para la ejecución e implementación de nuestras pruebas unitarias, sin embargo ¿Podríamos aplicar el mismo criterio si tuviéramos que testear programas que fueron realizados en COBOL o RPG? La respuesta es no, porque la Clase no existe como estructura en estos lenguajes. Entonces deberemos elegir otra unidad más apropiada a la tecnología con la que está construido ese sistema, quizás debiésemos considerar unidad a un programa entero, podríamos trabajar con las distintas subrutinas que lo componen, hay varias opciones que deberían ser analizadas.
Dije hasta el momento que para realizar una prueba unitaria es primero necesario definir a que llamaremos una unidad, y que esta definición depende en gran medida, aunque no solamente, de las restricciones o limitaciones de la propia tecnología utilizada en la construcción del sistema. Supongamos entonces que estamos trabajando con .Net como leguaje y nuestra aplicación está modelada siguiendo el paradigma de programación orientada a objetos. Siguiendo esta lógica definiremos como unidad una clase puesto que queremos llegar a una buena profundidad con nuestras pruebas unitarias. ¿Cómo se llevarían a cabo estas pruebas? ¿Qué habilidades debería tener desarrolladas una persona para ser capaz de realizar estas pruebas?
Normalmente suele decirse que las pruebas unitarias las realiza desarrollo, que son pruebas que el propio programador lleva adelante, sin embargo esto no tienen por qué ser así. Habiendo comenzado esta nota diciendo que la tecnología utilizada en la construcción de nuestro sistema influye en gran medida en la definición de unidad, resulta de alguna manera evidente que quien lleve a cabo las pruebas unitarias debe poseer habilidades técnicas de relevancia, en particular en este caso debería tener un conocimiento medianamente elevado en lo que a programación .Net se refiere y esto se debe a que, en su mayoría las pruebas unitarias son pruebas programadas. Pueden estar llevadas a cabo por el desarrollador, puede haber un equipo de testing qué, conociendo la estructura de las clases definidas se encargue de desarrollar scripts que consuman y hagan uso de las clases y métodos disponibles.
Las pruebas unitarias son pruebas técnicas, son pruebas que requieren de conocimiento técnico, leguajes de programación y la programación en sí misma. En una prueba unitaria se generarán arneses de prueba que se encargarán de llamar/ejecutar a nuestras unidades o que serán llamados/ejecutados por estas, la generación de dichos arneses de prueba es también parte del desarrollo de las pruebas unitarias. Mediante una prueba unitaria puedo detectar cuestiones tales como errores lógicos en la implementación de los métodos públicos y privados de una clase, atributos faltantes e incluso excepciones no controladas dentro de la propia clase y luego también analizar la cobertura que estas pruebas están realizando respecto a la totalidad del código, es decir cuánto código es ejecutado por mis pruebas.
En resumen podría decir que una prueba unitaria es una prueba técnica qué se lleva a cabo sobre una unidad y que requiere normalmente de conocimientos de programación. Qué puede o no ser llevada a cabo por testers y que es capaz de detectar errores lógicos y de estructura en las unidades probadas.
Pruebas de integración: las pruebas de integración dependen en gran medida de las decisiones y criterios que hayamos utilizado a la hora de definir nuestras pruebas unitarias y, si bien son independientes en cierta medida de estas, pierde sentido realizar pruebas de integración cuando no se llevaron a cabo pruebas unitarias. El objetivo de una prueba de integración es comprobar que nuestras unidades interactúan bien entre ellas, es decir que no hay conflictos entre las interfaces que se encargan de comunicar a nuestras unidades. Las pruebas de integración asumen que los componentes o unidades que van a integrarse fueron probados y que funcionan correctamente de forma independiente y se centra en las dificultades que puedan ocurrir durante su comunicación, de ahí que pierda un poco el sentido realizar una prueba de integración sino realicé una prueba unitaria con anterioridad puesto que puede no resultar claro si la falla se debe a una mala interacción entre las partes o al funcionamiento defectuoso de una de ellas.
Las pruebas de integración también requieren conocimientos técnicos y su efectividad depende en gran medida de la estrategia utilizada en la integración. Dije anteriormente que el objetivo de una prueba de integración es encontrar defectos en la comunicación entre las unidades que pueden deberse a diversas cuestiones como ser diferencias entre la cantidad de parámetros enviados, el tipo de datos de estos o incluso a problemas en la sincronización de diversos hilos de trabajo. En este nivel los arneses de prueba construidos comienzan a quitarse, según la estrategia de integración definida, y se reemplazan por unidades reales, también puede que se construyan otros arneses o se modifiquen los existentes porque por ejemplo un arnés resolviera lo realizado por varias unidades.
Me resulta necesario aclarar que una prueba de integración depende en gran medida de la definición que se haya dado de unidad, así podríamos por ejemplo estar hablando de la integración de diversos sistemas, módulos o funcionalidades y de cómo estos interactúan entre sí con todas las particularidades que esto implica.
Para resumir las pruebas de integración diría que son pruebas también técnicas, que su éxito depende mucho de la estrategia de integración utilizada y que tienen sentido si se llevaron a cabo las pruebas unitarias. Su objetivo es encontrar defectos en cuanto a la comunicación entre las unidades.
Prueba funcional o de sistema: si las pruebas unitarias o de integración requerían de un elevado nivel técnico, las pruebas de sistemas implican un gran conocimiento a nivel negocio. En estas pruebas nos enfocaremos desde el lado de un usuario y nos encargaremos de comprobar que la funcionalidad se aplicó de forma correcta y completa, es decir que verificaremos no sólo que el sistema lo que hace lo hace bien, sino que además comprobaremos que haga todo lo que tiene que hacer. Las pruebas de sistemas son en gran medida independientes de las de integración y unidad y, aunque no es recomendable, pueden llevarse a cabo si los anteriores niveles no se probaron puesto que el enfoque que realizan y los defectos que son capaces de encontrar son totalmente diferentes. Una prueba de sistema no podrá verificar si la comunicación entre las interfaces es correcta, tampoco podrá verificar si un unidad contiene o no problemas lógicos en su construcción, pero podrá detectar errores a nivel funcional, desde mensajes de error incorrectamente aplicados hasta validaciones no realizadas, a caminos que desde lo programático pueden parecer correctos pero que desde el punto de vista del negocio no sólo pueden no tener sentido, sino que hasta puede ser incorrecto o ilegal su recorrido. Las pruebas de sistema no sólo verificarán que el sistema funciona como un todo haciendo lo que tiene que hacer, de forma completa y bien, sino que además verificarán el cumplimiento normativas internas y/o legales que puedan estar regulando la actividad donde el sistema construido se desarrollará.
Resumiendo las pruebas funcionales se puede decir que su objetivo es comprobar la solución desde el punto de vista de un usuario, verificar y validar su correcto funcionamiento y completitud e incluso el acuerdo con las normas internas o legales que regulen la actividad donde el software producido ejerza sus funciones.
Espero que esta nota pueda aportar un poco de claridad en cuanto a que significa cada nivel de prueba ya que me encontré con errores conceptuales bastante importantes respecto a estos temas que llevan a confusiones bastante perjudiciales para los proyectos de construcción de software.
No hay comentarios:
Publicar un comentario