Saltar al contenido principal
Página

Tema 1.1 - Introducción

¿Qué es una prueba Unitaria?

Una Prueba unitaria es considerada como el alcance más pequeño que puede tener una prueba, es una fracción de código, en la que se busca asegurar que cada unidad (método o clase), de acuerdo a la programación orientada a objetos, funcione correctamente, usualmente posee una o varias entradas y una única salida.

 Las pruebas unitarias son desarrolladas mediante el método de pruebas de caja blanca y las cuales son normalmente creadas y ejecutadas por el/los desarrolladores en el mismo lenguaje de programación del SUT (Subject Under Test – Objeto de prueba). Se ejecutan antes de las pruebas de integración con el fin de verificar el correcto funcionamiento de manera atómica.

Las pruebas unitarias pueden desarrollarse de manera manual o automatizada, pero enfáticamente se recomienda que éstas sean automatizadas por todos los beneficios que esto representa.

Nota: En relación al alcance de una prueba unitaria, es posible hallar conceptos encontrados. De acuerdo a autores como Martin Fowler y Robert C. Martin, la definición de “unidad” es un tema situacional y el cual depende del equipo de trabajo. Si bien se inicia con la noción de unidad a partir de clases, es posible que una unidad esté compuesta por un grupo de clases o métodos relacionados y éstos sean tratadas como una unidad.


Tipos de Pruebas Unitarias

Hay una distinción importante que hacer respecto a las pruebas unitarias, en cuanto a la manera en que ellas se relacionan con el SUT (Subject Under Test). Si el SUT es una clase, es posible que dependa de otra clase (conocida como Depended-on Component, DOC). Si el DOC accede a disco o es un cliente de un sistema externo, se utiliza un doble (sustituto) de ese DOC. Los dobles se controlan desde el código de la prueba para comportarse de la forma más conveniente de cara al test que se esté implementando.

Por un lado, tenemos las pruebas unitarias Solitarias, las cuales son pruebas sobre un SUT con todos los DOC’s sustituidos por dobles (Test Doubles como veremos en capítulos posteriores).




Como se puede apreciar en la imagen, el SUT no tiene interacción con los componentes de los cuales depende (DOCs), por esta razón, se dice que la prueba es solitaria. Esto permite probar escenarios que podrían ser difíciles de probar con los DOCs reales o que no están disponibles porque están en fases de desarrollo.

Y por el otro lado, tenemos las pruebas unitarias Sociables, las cuales usan los DOCs reales para hacer la prueba unitaria del SUT.




Este tipo de pruebas unitarias son más fáciles de implementar porque se usan menos dobles y por ende son menos frágiles porque un cambio del código de producción se aprovecha en la prueba, mientras que con las pruebas solitarias es necesario actualizar los dobles con cada cambio de diseño.


Características de las pruebas unitarias

Ahora veamos ese conjunto de características que definen la calidad de una prueba unitaria.

  • Tienen que poder ejecutarse sin intervención manual.
  • Son ejecutadas en completo aislamiento.
  • Se ejecutan MUY rápido.
  • Si fallan, apuntan directamente a la fuente del bug.
  • Brindan un feed back inmediato cuando éstas son ejecutadas.


Para que estas características se cumplan, existen lo que se conoce como “Los Principios FIRST”, en otras palabras, estas son las características que determinan que nuestras pruebas unitarias son de calidad. Veámoslos en detalle:

  1. FAST (Rápidas): La ejecución de las pruebas unitarias es MUY rápida, lo que brinda la posibilidad de ejecutar un gran número de pruebas en cuestión de segundos. Esto posibilita  ejecutar las pruebas muy frecuentemente y con ello detectar bugs de forma muy rápida y sencilla. En caso de aumentar considerablemente el número de pruebas unitarias de un proyecto, el tiempo de ejecución total no debería verse muy afectado. Esto tiene bastante sentido si pensamos que normalmente de desarrollan este tipo de pruebas con el fin de alcanzar una alta cobertura del código por medio de éstas.

  2. INDEPENDENT (Independientes): Por muchas pruebas unitarias que tengamos, todas deben de ser independientes de las otras. En el momento que una prueba falla por el orden en el que se ha ejecutado, tenemos claro que esta prueba está mal desarrollada. El resultado no debe verse alterado ejecutando las pruebas en un orden u otro o incluso de forma independiente. Se puede dar el caso de que un test falle al ejecutar los cientos o miles que tiene el proyecto. En esta situación podríamos debugger de forma más rápida y sencilla si sólo podemos ejecutar el test fallado obteniendo el mismo resultado de ejecutarlo en conjunto.

  3. REPEATABLE (Repetibles): Las pruebas unitarias deben poder ser ejecutadas en cualquier entorno / ambiente, es decir, no deben existir dependencias con el host en el que se están ejecutando las pruebas. Es muy común encontrar pruebas e incluso código del software en desarrollo que pasa o se ejecuta en el ordenador de la persona que lo desarrolló, pero no pasa lo mismo cuando este es ejecutado en un equipo diferente.

  4. SELF-VALIDATING (Auto evaluables): Uno de los puntos a favor de pruebas automatizadas es que podemos ejecutarlas simplemente al pulsar un botón o incluso hacer que se ejecuten de forma automática tras otro proceso. De nada nos serviría si una vez ejecutadas tuviéramos que estar trasteando ficheros, comprobando valores o realizando otras tareas engorrosas para comprobar el resultado de los tests ejecutados.
    Las pruebas deben tener una salida booleana la cual nos indica si la prueba pasa o no pasa, lo cual hace que el test cuando se evalúe a sí mismo nos brinde un resultado fácilmente legible.

  5. TIMELY (Oportunas): Esta última característica se basa en cuándo deberíamos tener desarrolladas las pruebas, que deben estar desarrolladas lo antes posible y siempre antes de subir código a producción. A ser posible, las pruebas deben desarrollarse antes de empezar a desarrollar el código de la aplicación (TDD).


Ventajas de pruebas unitarias

  • Al estar en la base de la pirámide de pruebas automatizadas y ser más rápidas permiten encontrar más bugs en etapas tempranas del SDLC (Software Development Life Cycle).
  • No tienen dependencias con otros sistemas y pruebas.
  • Son fáciles de construir.
  • Para el desarrollador se presentará una mejora en la calidad del código, ya que se reducirán los tiempos de depuración y corrección de incidencia.
  • Posibilita el cambio y la refactorización, esto hace que el código cada vez tenga mejores características y más calidad, lo que conduce a una implementación más limpia y con menos errores.
  • En las pruebas unitarias se reducen los problemas y tiempos dedicados a la integración, ya que se simulan las dependencias que permiten probar el código, sin disponer del resto de los módulos.
  • La prueba unitaria da un entendimiento del funcionamiento del código, dando un conocimiento acerca de qué hace determinado código y qué se espera de él.


¿Qué no es una prueba Unitaria?

Como se mencionó anteriormente una prueba unitaria es el alcance más pequeño de una prueba y por ende su alcance es muy puntual (el código bajo prueba). A continuación, veremos algunos ejemplos de cuándo una prueba deja de ser una prueba unitaria:

  • Si la prueba habla con la BD.
  • Si la prueba se comunica a través de red.
  • Si la prueba toca el file System.
  • Si las pruebas no pueden correr al mismo tiempo.

Última modificación: miércoles, 16 de marzo de 2022, 12:57