jasmine: 1. suites y matchs

Hola Mundo en jasmineano

Lawrence Alma-Tadema

archivado en: JavaScript / 26 abril, 2015 / taller:

Comienzo con esta entrada un taller dedicado a los test en javaScript. En general, la literatura sobre los test suele empezar con la parte teórica y termina con la práctica, sin embargo, salvo una breve introducción, haré lo contrario, pues creo que algunos planteamientos abstractos quedarán más claros si los podemos concretar en algo de código.

Los test consisten en una batería de algoritmos que evalúan si en determinadas partes de una aplicación se obtiene el resultado esperado según unas premisas de partida. Por ejemplo, si introducimos tal y cual dato en un formulario, el resultado debe ser un json con este y aquel dato.

En muchas ocasiones se afirma que toda aplicación debe contar con tests que cubran el n por ciento de la misma. Sin embargo, como suele suceder con las afirmación categóricas, conviene manejarlas con cautela cuando bajamos al mundo real. Los test hay que escribirlos y luego mantenerlos y eso tiene un coste. Y un test automático no evalúa los aspectos subjetivos de la aplicación, como la usabilidad o la bondad del diseño, por lo que no reemplaza al equipo de testers humanos especialistas en ux. Por lo tanto, antes de embarcarse en unos test «que cubran el 80 por ciento de la aplicación», tal y como gustan alardear los comerciales, hay que fijarse bien en que no se esté pretendiendo matar moscas a cañonazos.

Sin remontarnos al testozeno inferior, muchos de los distintos tipos de test que existen hoy en día se derivan de la propuesta metodológica del «desarrollo orientado o dirigido por pruebas», en inglés test-driven development, más conocido por su abreviatura: TDD. Esta metodología consiste, en esencia, en desarrollar primero una serie de test y luego el código necesario para superarlos. Por ejemplo, imaginemos que tenemos que desarrollar el catálogo de una biblioteca. Primero haríamos un test que evaluase si al pulsar sobre un título se mostrase un pdf y luego ya desarrollaríamos el código necesario para que se cumpliese esa condición.

De los TDD se derivan los «test orientados al comportamiento», behavior-driven development (BDD), que no miran solo un detalle de todo el proceso, sino el escenario completo. Bueno, como dije, volveré sobre este tema más adelante, una vez que veamos algo de código.

Jasmine

Jasmine es un framework para realizar test BDD en javaScript. Para instalarlo sin más, lo que denominan jasmine standalone, lo más rápido es instalarlo a mano:

1. Abrimos la consola de git y clonamos en cualquier lado el repo de jasmine.

git clone https://github.com/jasmine/jasmine.git

2. nos vamos al directorio de nuestro proyecto, que en este ejemplo he denominado laboJasmine.

mkdir laboJasmine && cd laboJasmine

3. Creamos un subdirectorio llamado jasmine.

mkdir jasmine

4. Y ahí unzipeamos la última versión de jasmine que hay en el directorio dist del repo que nos hemos bajado, que en el momento de escribir estas líneas es la jasmine-standalone-2.2.0. Este proceso lo podemos hacer de forma manual o por consola.

unzip jasmine-standalone-2.0.0.zip

5. Borramos los ejemplos que trae (o los movemos a otro lado para estudiarlos en otro momento), de tal manera que al final nos queda algo así:

nuestraAplicacion

-/jasmine

--/lib: todo el tinglado de la librería

--/src: los archivos que queremos testar

--/spec: un directorio vacío donde pondremos los test

-archivoComoSeLlame.html

6. En el documento html, que en el zip llaman SpecRunner.html, pero que podemos llamar como sea, enlazamos todos los archivos.

SpecRunner.html

<!-- Algo de estilos pa que se vea bonico -->

<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-2.0.0/jasmine_favicon.png">

<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-2.0.0/jasmine.css">

<!-- El core de la librería jasmine -->

<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine.js"></script>

<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine-html.js"></script>

<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/boot.js"></script>

<!-- Los archivos a testar -->

<script src="src/ARCHIVOATESTAR.js"></script>

<!-- Los test -->

<script src="src/TESTSPEC.js"></script>

Para instalar un scaffolding más complejo, tiramos de npm:

npm install --save-dev jasmine

Hola mundo... o parecido

Con todo listo, vamos a preparar el equivalente a un hola mundo en jasmineano. Imaginemos que tenemos una aplicación de lo más apañada que suma y resta dos números. En un archivo llamado operaciones.js, algo así:

operaciones.js

var todoOperaciones = {

sumar: function(foo, bar) {

return foo + bar;

},

restar: function(foo, bar) {

return foo - bar;

}

}

var todoNumeros = {

foo: 4,

bar: 6

}

todoOperaciones.sumar(todoNumeros.foo, todoNumeros.bar);

todoOperaciones.restar(todoNumeros.foo, todoNumeros.bar);

Ahora en un archivo que podemos llamar operacionesSpec.js, o similar, vamos a escribir el test o spec, abreviatura de specification.

Un test en jasmine está formado por distintas suites, cada una de las cuales analizan un fragmento del código. Cada suite se define en una una función denominada describe, que recibe como primer parámetro una cadena con el título o nombre que le pongamos a la suite.

El segundo parámetro es una función en la que indicamos en una o más funciones lo que debe suceder. Estas funciones se llaman it y tienen como primer parámetro una cadena que luego se muestra en el informe final. Conviene escribirla en inglés y lo más concreta y precisa posible.

Por último, dentro de cada it hay un match, lo que se está buscando y que traducido vendía a ser algo así como "espero que (esto).sea(estoOtro)". Por ejemplo, esta sería una suite para probar si foo es 4.

operacionesSpec.js

describe("todoOperaciones", function() {

it("foo must be 4", function() {

expect(todoNumeros.foo).toEqual(4);

});

});

Si ahora abrimos SpecRunner.html, donde hemos enlazado operaciones.js y operacionesSpec.js, el test nos aparecerá en verde, signo de que no hay errores.

jasmine_01

 

Cada suite debe analizar solo una funcionalidad concreta del código, no hay que utilizar la misma para todo.

Matches principales

1. toEqual

Es el match más sencillo y, como vimos, comprueba que algo sea igual a algo.

describe("types", function() {

var testBar = typeof todoNumeros.bar;

it("bar must be number", function() {

expect(testBar).toEqual('number');

});

});

Los matches se pueden "negar" para buscar el resultado contrario (como cuando anteponemos una ! en un condicional)

expect(todoNumeros.foo).not.toEqual(4);

2. toBe

Algo debe ser lo mismo que algo, es decir, deben ser de la misma naturaleza, como cuando hacemos una equiparación con el triple igual. Por ejemplo, este test falla porque foo y bar son distintos, uno es un número y el otro un literal.

describe("number", function() {

var foo = "10";

var bar = 10;

it('should check that foo is the same as bar', function() {

expect(foo).toBe(bar);

});

});

3. toBeTruthy / toBeFalsy()

Comprueban que un valor sea verdadero (true) o falso (false). Por ejemplo, este test saldría bien si un número es par y viceversa.

describe("even", function() {

var testEven = todoNumeros.foo % 2;

testEven = ( testEven == 0 ) ? true : false;

it("The number must be even", function() {

expect(testEven).toBeTruthy();

});

});

Ojo, esto es javaScript, así que los siguientes valores son false (y viceversa):

  • false
  • 0
  • "" (cadena vacía)
  • undefined
  • null
  • NaN

4. toContain

Evalúa si un elemento -como un array o una cadena- contiene otro.

expect(["foo", "bar", "bazinga"]).toContain("foo");

expect("hagaBasin").toContain("Basin");

5. Nulos, indefinidos y cosas que no son números

No entro a explicarlos porque son evidentes:

  • toBeDefined, toBeUndefined: si el valor está definido o no.
  • toBeNull: si es nulo
  • toBeNaN(): si no es un número (not a number).

Ojo, a veces isNan() nos da sorpresas. Utilizar mejor un typeof.

6. Comparadores

Sirven para números y cadenas (que se ordenan alfabéticamente)

  • toBeGreaterThan: debe ser mayor que algo.
  • toBeLessThan: debe ser menor que algo.

Hay algún match predefinido más, como toThrow() para capturar excepciones o toMatch(), para expresiones regulares, pero me remito a la documentación de la librería para quien quiera profundizar sobre el tema. De momento, vamos a dejarlo aquí.

|| Tags: , , , ,

valoración de los lectores sobre jasmine: 1. suites y matchs

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración negativa
  • 4.3 sobre 5 (6 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Aportar un comentario


*