Pruebas unitarias, los primeros pasos.

Héctor Varas
5 min readFeb 27, 2017

--

Hoy escribiré sobre un tema muy importante pero que siempre dejamos de lado a la hora de Trabajar en un proyecto. ¿Alguna idea?.

Exacto, hoy veremos cuál IDE de desarrollo es mejor. Es broma! :B, veremos como hacer test unitarios.
Es un “hecho” que todo desarrollador en un comienzo, cuando se ve frente al tema de Pruebas unitarias dice cosas como: “¡Que fastidio tener que hacer pruebas para cada cosa que desarrollo!” o “Que perdida de tiempo”, “Si ya funciona ¿Para qué tengo que probarlo?” Esto porque aún no vemos sus potenciales ventajas y solo vemos desventajas.
Para mi, una ventaja importante del uso de pruebas unitarias es que al programar en base a funciones que puedes separar y abstraer completamente de la ejecución, te permite realizar rápidas comprobaciones de si funciona o no. Puedes revisar y cubrir aquellas cosas que incluso no habías contemplado solamente por la facilidad de lectura que tiene el resultado de tu código. En caso contrario aplicar Test-driven development (TDD) te obliga a refactorizar tu código en uno mucho mas ordenado y legible, además de funcional y bueno, luego que le tomas el hilo verás que no son tan complicados y que sirven bastante, sobre todo para confiar en que nuestro código si funciona. De vez en cuando es probable que algunos te den dolor de cabeza, pero son gajes del oficio.

Las herramientas

En esta ocasión usaremos las siguientes herramientas, Mocha, Chai y Sinon.
Mocha es un Test Framework que corre bajo Node, no es el único por cierto pero tiene gran cantidad de usuarios que reafirman mi confianza en su uso.
Chai es una librería de asserts que amplía la lista de posibilidades entregadas por Mocha. Además quise incluir Sinon pues me toco usarlo hace poco y lo encontré útil. Su principal función es poder realizar tests a las funciones o callbacks de funciones que no son triviales o fáciles de cubrir.

Partimos…

Lo primero será inicializar nuestro proyecto e instalar los paquetes antes mencionados.

$ npm init
$ npm install -- save mocha chai sinon

Ahora creamos un archivo llamado module-test.js dentro de un directorio libraries, donde pondremos algunas funciones que luego probaremos.

Luego creamos otro directorio de nombre tests y dentro un archivo “module.test.js

Escribimos una pequeña función en nuestro archivo de funciones
module-test.js

function sayMyname(name) {
return `Your name is ${name}`;
}

module.exports = sayMyname;

Por otra parte en nuestro archivo de tests creamos la descripción que debe validar si nuestro código cumple la condición.

var assert = require('assert');
var sayMyname = require('../libraries/module-test');


describe('## MODULE TEST', () => {
describe('# Say my name ', () => {
it('should show my name ', () => {
assert.equal('Your name is Hector',sayMyname('Hector'));
});
});
});

Lo que hacemos aquí es importar la función assert de mocha.
Importamos nuestra función sayMyname del modulo que creamos anteriormente.
Seguido por un Describe donde indicamos que vamos a testear, luego un it donde ponemos lo que debería hacer el test.

Los tests deben ser muy simples y con ellos deben probar el funcionamiento de módulos o funciones especificas de manera de asegurar el código lo más modular y abstracto posible.

Usando Chai

Ahora veamos como queda el ejemplo usando la librería de asserts chai y usando su función expect. Esto nos permite evaluar la función y el resultado en base a una condición.

var chai = require('chai');
var sayMyname = require('../libraries/module-test');
var expect = chai.expect;


describe('## MODULE TEST', () => {
describe('# Say my name ', () => {
it('should show my name ', () => {
expect(sayMyname('Hector')).to.be.equal('Your name is Hector');
});
it('should sayMyname to be a string ', () => {
expect(sayMyname('Hector')).to.be.a('string');
});
});
});

En el ejemplo agregamos chai con un require a la librería e importamos expect. Puedo agregar cuantos test crea necesarios dentro de un describe o crear otros describes nuevos y más tests.

Ejecutamos el test

$ ./node_modules/.bin/mocha tests## MODULE TEST
# Say my name
✓ should show my name
✓ should sayMyname to be a string
2 passing (9ms)

Usando Sinon

Aveces nos pasa que al modularizar nuestras funciones no retornan un valor explícito o retornamos los resultados a través de callbacks en funciones asyncronas. Pues Sinon nos provee la manera de evaluar si nuestra función escapo por un callback sin tener que revisar que realizó en dicho callback. Para ello utilizaremos una de las funciones llamada spy.

Veamos un ejemplo

Primero en nuestro archivo de funciones module-test.js agregamos la siguiente función y la exportamos.

function myFunction(condition, callback){
if(condition){
callback();
}
}

Por otra parte en nuestro archivo de tests module.test.js agregamos el test que nos permitirá evaluar esa función.

describe('# myFunction', () => {
it('should call the callback function', () => {
var callback = sinon.spy();

myFunction(true, callback);

assert(callback.calledOnce, 'Condition was false');
});
});

Lo que hacemos es usar spy para espiar el callback y poder evaluar si fue ejecutado. Además agregamos un mensaje para el assertError en caso que no se cumpla.
Así podemos hacer test bien abstractos sin esperar por una respuesta de una ejecución de mucho código.

Sinon también tiene otras herramientas útiles como stubs para reemplazar la ejecución de funciones y así lograr asserts en acciones poco probables o crear servidores falsos o timers falsos para cubrir test que tengan estos requisitos, pero eso lo veremos en otra entrega.

El ejemplo completo lo pueden clonar desde:

Espero les guste y haya quedado más claro el uso de test unitarios. Nos vemos en otro post.

--

--