jueves, 30 de agosto de 2012

Haciendo test en javascript con jasmine

Antes de irme de vacaciones asistí a unas charlas denominadas #jsweek dadas por el grupo @agileCanarias. La charlas fueron impartidas por @ydarias y por @axelhzf, y se tocaron temas tan divertidos como los WTF de javascript, CoffeeScript y Backbone.

Bien, en la charla de introducción a javascript aprendí a usar jasmine, que no es otra cosa que un framework para hacer test unitarios en javascript. A medida que escribíamos los test para la kata fizzbuzz me di cuenta que podría aplicar este framework a mi método de comparación de objetos que expliqué en mi anterior post (Comparando objetos en javascript)

Sin ser un experto, o más bien, considerándome un neófito en esto de los test unitarios, lo primero que debemos hacer es bajarnos el framework desde su página web. Una vez descargado y descomprimido veremos que tenemos la siguiente estructura
  • Un fichero SpecRunner.html desde donde se ejecutaran los test que definamos.
  • Una carpeta lib donde esta el propio framework y donde en principio no tenemos que tocar nada.
  • Una carpeta spec donde irán los test que queremos ejecutar.
  • Una carpeta src donde irá el código que queremos probrar.
En mi caso he creado un proyecto llamado HelperJS con un fichero prototypes.js donde está el código descrito en el post anterior y una carpeta test que tiene la estructura anteriormente descrita. Ahora lo que haremos será abrir el fichero SpectRunner.html y añadiremos las referencias a los ficheros de test y ded código que queremos probar.
<!-- include spec files here... -->
<script type="text/javascript" src="spec/prototypesSpec.js"></script>

<!-- include source files here... -->
<script type="text/javascript" src="../prototypes.js"></script>
Si abrimos la página SpecRunner.html en el navegador obtendremos una página vacia, por lo que lo siguiente será escribir los test en el fichero prototypesSpec.js. Siguiendo un poco la métodología TDD (y repito que soy un novato total en el tema) lo normal es escribir los test de lo más simple a lo más complejo (aunque en mi caso el código ya está escrito). Basándome en esto lo más simple es escribir un test para cuando el segundo objeto es null o undefined. Con esto podemos escribir nuestro primeros test de la siguiente manera
describe("Object.prototype.equals", function() {
 it("El objeto a comparar es null", function() {
  var u1 = {prop1: "1", prop2: 2};
  var u2 = null;

  expect(u1.equals(u2)).toBe(false);
 });

 it("El objeto a comparar es undefined", function() {
  var u1 = {prop1: "1", prop2: 2};
  var u2 = undefined;

  expect(u1.equals(u2)).toBe(false);
 });
});
Como vemos el código es bastante fácil de entender. El método describe se usar para definir un grupo de test (u otro grupo) y le pasamos una función donde se definen los test. Para definir un test usamos el método it, al que le pasamos una descripción del test y un función donde se ejecuta el test gracias a expect donde indicamos lo que queremos probar y el valor que debe tener. Si todo ha ido bien al recargar la página SpecRunner.html debemos obtener algo como esto


Con esto claro, ya podemos escribir el resto de test en lo que comprobamos distintas posibilidades que se pueden dar.
describe("Object.prototype.equals", function() {
 it("El objeto a comparar es null", function() {
  var u1 = {prop1: "1", prop2: 2};
  var u2 = null;

  expect(u1.equals(u2)).toBe(false);
 });

 it("El objeto a comparar es undefined", function() {
  var u1 = {prop1: "1", prop2: 2};
  var u2 = undefined;

  expect(u1.equals(u2)).toBe(false);
 });

 it("Distinto numero de propiedades", function() {
  var u1= {prop1 : "value1", prop2: 2};  
  var u2= {prop1 : "value1", prop2: 2, prop3: 3};  

  expect(u1.equals(u2)).toBe(false);
 });

 it("Mismas propiedades pero con distintos valores", function() {
  var u1= {prop1 : "value1", prop2: 2};  
  var u2= {prop1 : "value1", prop2: 3};  

  expect(u1.equals(u2)).toBe(false);
 }); 

 it("Mismo numero de propiedades pero con nombres distintos", function() {
  var u1= {prop1 : "value1", prop2: 2};  
  var u2= {prop1 : "value1", prop3: 3};  

  expect(u1.equals(u2)).toBe(false);
 }); 
  
 it("Dos objetos simples iguales", function() {
  var u1 = {prop1: "1", prop2: 2};
  var u2 = {prop1: "1", prop2: 2};

  expect(u1.equals(u2)).toBe(true);
 });

 it("Dos objetos compuestos distintos", function() {
  var u1 = {prop1: "1", prop2: 2, prop3: { prop4: 4}};
  var u2 = {prop1: "1", prop2: 2, prop3: { prop5: 5}};

  expect(u1.equals(u2)).toBe(false);
 });

 it("Dos objetos compuestos iguales", function() {
  var u1 = {prop1: "1", prop2: 2, prop3: { prop4: 4}};
  var u2 = {prop1: "1", prop2: 2, prop3: { prop4: 4}};

  expect(u1.equals(u2)).toBe(true);
 });
});
Obteniendo la siguiente salida


Como vemos es bastante fácil escribir test simples para nuestro código javascript. Si estás interesado en probar otros framework de este tipo también está QUnit que por lo que me han comentado también está bastante bien.

Todo esta código espero subirlo próximamente a GitHub.

Happy coding!

No hay comentarios:

Publicar un comentario