“¡No hay tiempo para hacer tests unitarios!”. Algunas empresas de desarrollo de software utilizan esta frase con asiduidad sin analizar con detenimiento sus consecuencias en tiempo, dinero y esfuerzo para un equipo de desarrollo y, por tanto, para la propia empresa.

Sin embargo, existen otras empresas como Paradigma Digital que en la actualidad están intentando hacer un esfuerzo por incorporar la realización de tests desde el inicio del desarrollo e intentan que crezcan proporcionalmente con él.

Para quien no sepa de qué estamos hablando, los tests o pruebas unitarias son un mecanismo utilizado en desarrollo de aplicaciones que permiten comprobar el correcto funcionamiento de nuestros módulos, funciones o clases desarrolladas.

[caption id="attachment_4343" align="aligncenter" width="780"]

QA2 Bug 780 ok

Fuente: https://techsergioflores.wordpress.com/[/caption]

A priori, multitud de clientes no son conscientes de por qué es tan importante realizar estos tests o pruebas unitarias, ya que conceptualmente no aportan un valor claro al producto que se desarrolla para ellos: los usuarios no los utilizan, el cliente tampoco, y con ellos el producto final es, a la vista, exactamente igual que si no se hubieran desarrollado.

Pero veámoslo desde otro punto de vista. Que un producto sea o no de calidad, no sólo se consigue invirtiendo un tiempo valioso en la capa que va a interactuar con el usuario. Es una capa vital para el proyecto, pero no la única que aporta valor al mismo. Igualmente importante es la arquitectura y desarrollo técnico en la que se apoya esta capa visible y que conjuntamente a la capa visual aporta una experiencia final satisfactoria. ¿De qué nos sirve una gran interfaz si, cuando voy a hacer una compra de entradas para el concierto de mi grupo favorito, el módulo de venta de entradas tiene un bug y no me permite comprar?

La experiencia nos ha enseñado que los bugs son imposibles de evitar, y menos en procesos de Continuous Delivery donde hay nuevas versiones que refactorizan o incorporan nuevos módulos al proyecto. Sin embargo, existen mecanismos que nos aportan valor a un producto simplemente garantizando que un módulo, cuando es modificado en una nueva versión, sigue manteniendo la funcionalidad intacta y permite garantizar que todo va a funcionar como uno espera. Y esto, no lo consigue un ser humano probando 24 horas por 7 días a la semana. Lo consiguen los tests.

Los tests unitarios deben comprobar que una función que se ha programado, siempre debe funcionar igual. Pongamos un ejemplo muy sencillo: supongamos que desarrollamos una función que, recibiendo dos variables, debe devolver la multiplicación de ambas. Un ejemplo de esta función, programada en el lenguaje de programación Python, sería el siguiente:


def multiplication(a, b):
    return a*b

Para asegurarnos de que esta función siempre va a funcionar igual, es indispensable dedicar unos minutos a desarrollar un test que compruebe su funcionalidad. Un ejemplo de test unitario en Python para esta función sería el siguiente:


import unittest
class SampleTestCase(unittest.TestCase):
    def setUp(self):
        self.a = 3
        self.b = 4
    def test_multiplication(self):
        self.assertEqual(multiplication(self.a, self.b), 12)

Con este pequeño test, nos aseguramos para siempre que la función siempre nos devolverá la multiplicación de ambos números. Si alguien del equipo modifica esta función y el test falla, sabremos que existe un bug antes de que el fallo llegue a producción. Sin él, en un proyecto de decenas de miles de líneas de código fuente lo más probable es que el bug no sea detectado hasta estar en producción.

Es de vital importancia que la cobertura de los tests unitarios -el número de líneas cubiertas por los tests- sea de un porcentaje como mínimo del 80% del código desarrollado. Cuanto mayor sea este porcentaje de cobertura, mayor será la robustez que los tests aportan a nuestro proyecto, y en la misma proporción aumentará el nivel de confianza que, no solo el equipo de desarrollo tenga sobre la fiabilidad de su código, sino también el equipo de sistemas y en última instancia los stakeholders (los usuarios del cliente).

Hay que destacar que los tests unitarios no van a garantizar por sí solos todos los flujos de una aplicación. Para garantizarlos, es necesario desarrollar otro tipo de tests que completen a estos tests unitarios. Estos tests, desarrollados por equipos especializados de QA, son tests de integración y flujos automatizados (que habitualmente validan la interfaz de la aplicación), los cuales no comprueban los métodos y funciones programados de manera unívoca, sino que confirman que el flujo que debe realizar el usuario final, funciona como el cliente que ha contratado el proyecto.

anand-bagmar-behavior-driven-testing-bdt-in-agile-7-728

Fuente: Anand Bagmar (SiliconIndia's SoftTec 2012)

Pirámide de tests: de unidad, de integración y de flujos (UI)

Todo este esfuerzo de los equipos por garantizar la robustez de un proyecto, es indispensable para que una aplicación se desarrolle con garantías. No es una pérdida de dinero, no es una pérdida de tiempo… Es una inversión a largo plazo. Y si el proyecto es robusto y se apoya en estas técnicas, que no quepa ninguna duda de que la empresa se beneficiará positivamente de esta buena práctica, y sus clientes, volverán a confiar en ellos para nuevos proyectos que quieran llevar a cabo.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.