JsTestDriver: testea tu código Javascript.
0. Índice de contenidos.
- 1. Introducción.
- 2. Entorno.
- 3. El escenario.
- 4. Escribiendo los test.
- 5. Arrancando el servidor.
- 6. Ejecutando los test.
- 7. Referencias.
- 8. Conclusiones.
1. Introducción
Todos tenemos muy claro la importancia de tener un código bien testeado que sea robusto y flexible a cambios. Que si cambio una cosa no me cargue el funcionamiento de otra. Estamos acostumbrados a usar frameworks como JUnit para testear nuestro código Java, pero… ¿qué pasa con nuestro código Javascript?. Con Javascript, en caso de que se produzca un error, por norma general no vamos a tener una traza de error en nuestro servidor (aunque hay librerías de log´s para js). Lo más probable es que al usuario no le funcione bien la aplicación o que, directamente la pantalla no haga nada (caso de que salte una excepción). Además, en algunas ocasiones, el código no se comporta de la misma forma en diferentes navegadores (sobre todo cuando interactuamos con elementos del DOM).
En este tutorial vamos a intentar explicar cómo testear nuestro código Javascript con diferentes navegadores gracias al framework JsTestDriver.
2. Entorno.
El tutorial está escrito usando el siguiente entorno:
- Hardware: Portátil MacBook Pro 15′ (2.2 Ghz Intel Core I7, 8GB DDR3).
- Sistema Operativo: Mac OS Snow Leopard 10.6.7
- Entorno de desarrollo: Eclipse 3.7 Indigo.
- JsTestDriver 1.3.4.
- Mozilla Firefox 10.0.2.
- Google Chrome 17.
- Safari 5.1.
3. El escenario.
Supongamos que, en un directorio llamado js de nuestra aplicación, tenemos una libería Javascript llamada validador.js con las siguientes características:
- Contiene una clase a la que hemos llamado Validador, cuyos objetos se construyen recibiendo como parámetro un formulario.
- La clase tiene un método validar que validará todos los elementos del formulario.
- Si un elemento tiene un className igual a obligatorio (class=»obligatorio») se comprobará que su valor no sea vacío.
- Si todos los elementos se validaron correctamente devolverá el mensaje «OK».
- Si un elemento no cumpliese con la validación se devolverá un mensaje informando de que ese campo tiene un valor incorrecto.
El código es el siguiente:
function Validador(formulario) { this.form = formulario; } Validador.prototype.validar = function () { var elementos = this.form.childNodes; for (var i = 0; i < elementos.length; i++) { var elemento = elementos[i]; if (elemento.className == 'obligatorio' && elemento.value == '') { return "El campo " + elemento.name + " es obligatorio"; } } return "OK"; };
Y un ejemplo de un formulario que se podría validar con este código sería el siguiente:
<form action="loquesea"> Nombre: <input type="text" class="obligatorio" name="nombre"/> Cargo: <select class="obligatorio" name="cargo"> <option value=""></option> <option value="Jefe">Jefe</option> <option value="Becario">Becario</option> </select> Edad: <input type="text" name="edad"/> </form>
Obsérvese que los campos Nombre y Cargo están marcados como obligatorios.
4. Escribiendo los test.
Para escribir los tests que se ejecutarán sobre el código del punto anterior, creamos un directorio js-test a la misma altura del directorio js donde teníamos nuestro validador.js. Dentro del dicho directorio, creamos un fichero validador-test.js donde escribiremos nuestros test. Vamos a utilizar como escenario el formulario propuesto en el punto anterior. Probaremos lo siguiente:
- Si se intenta validar un formulario con el valor del campo «nombre» igual a vacío debe devolver un mensaje de error indicando que el nombre es obligatorio.
- Si se intenta validar un formulario con el valor del campo «nombre» distinto a vacío pero con el valor del campo «cargo» igual a vacío debe dar un mensaje de error indicando que dicho campo es obligatorio.
- Si los campos «nombre» y «cargo» no son vacíos debe devolver OK.
El código de nuestro validador-test.js es el siguiente.
ValidadorTest = TestCase("ValidadorTest"); ValidadorTest.prototype.testDebeAvisarmeSiElNombreNoEstaPuesto = function() { /*:DOC form = <form action="loquesea"> Nombre: <input type="text" class="obligatorio" name="nombre"/> Cargo: <select class="obligatorio" name="cargo"> <option value=""></option> <option value="Jefe">Jefe</option> <option value="Becario">Becario</option> </select> Edad: <input type="text" name="edad"/> </form> */ var validador = new Validador(this.form); assertEquals("El campo nombre es obligatorio", validador.validar()); }; ValidadorTest.prototype.testDebeAvisarmeSiElCargoNoEstaPuesto = function() { /*:DOC form = <form action="loquesea"> Nombre: <input type="text" class="obligatorio" name="nombre" value="Pepe"/> Cargo: <select class="obligatorio" name="cargo"> <option value=""></option> <option value="Jefe">Jefe</option> <option value="Becario">Becario</option> </select> Edad: <input type="text" name="edad"/> </form> */ var validador = new Validador(this.form); assertEquals("El campo cargo es obligatorio", validador.validar()); }; ValidadorTest.prototype.testDebeAvisarmeSiEstaTodoOK = function() { /*:DOC form = <form action="loquesea"> Nombre: <input type="text" class="obligatorio" name="nombre" value="Pepe"/> Cargo: <select class="obligatorio" name="cargo"> <option value=""></option> <option value="Jefe" selected="selected">Jefe</option> <option value="Becario">Becario</option> </select> Edad: <input type="text" name="edad"/> </form> */ var validador = new Validador(this.form); assertEquals("OK", validador.validar()); };
Sobre el código anterior debemos tener en cuenta las siguientes consideraciones:
- El nombre del test (del método) debe empezar por «test» para que el framework sepa que es un test (ej:testDebeAvisarmeSiEstaTodoOK).
- Obsérvese que para hacer que los test actuen sobre un formulario HTML con unas carácterísticas concretas lo hacemos introduciéndolo de la forma /*:DOC form = código HTML */ dentro del método del test.
- Si quisiésemos hacer inicializaciones antes de cada test, deberíamos hacerlo con un método llamado setUp (ej: ValidadorTest.prototype.setUp)
5. Arrancando el servidor.
JsTestDriver nos provee de un ligerísimo servidor web donde deben conectarse nuestros navegadores para que el código Javascript que vamos a testear pueda ser ejecutado en ellos y así poder evaluar el comportamiento del código.
Pues bien, lo primero que debemos hacer es descargarnos la librería que arrancará el servidor y ejecutará los test. Seleccionamos el enlace que pone «Self-contained executable jar».
Lo siguiente que hacemos es copiar el archivo descargado (.jar) en el directorio desde el que vamos a arrancar el servidor y ejectuar los test.
A continuación, creamos un fichero en el mismo directorio donde hemos copiado el jar, llamado jsTestDriver.conf. En este fichero configuraremos las características de la ejecución de nuestros tests. En nuestro caso únicamente le diremos donde está el servidor, la ruta de los ficheros a testear y la ruta de los tests.
server: http://localhost:9876 load: - js/*.js - js-test/*.js
Ahora ya podemos arrancar el servidor. Vamos al directorio donde tenemos el jar y el fichero de configuración y escribimos lo siguiente:
java -jar JsTestDriver-1.3.4.b.jar --port 9876
Y por último nos conectamos con los navegadores que deseamos evaluar al servidor con la siguiente URL: localhost:9876/capture
Nos aparecerá una pantalla como la siguiente:
También podemos hacerlo todo de golpe, arrancando el servidor e indicándole la ruta de los navegadores (separados por comas) con los que queremos testear el código de la siguiente forma:
java -jar JsTestDriver-1.3.4.b.jar --port 9876 --browser /Applications/Google\ Chrome.app/
6. Ejecutando los test.
Una vez que ya tenemos el servidor arrancado y los navegadores conectados al servidor, lo último que queda es lanzar los test. Para ello, en el directorio del jar y el .conf escribimos lo siguiente:
java -jar JsTestDriver-1.3.4.b.jar --tests all --verbose
Y como se ve en la imagen, todos los test han pasado en los tres navegadores en los que se ha testeado: Safari, Firefox y Google Chrome.
7. Referencias.
8. Conclusiones.
En este tutorial hemos visto cómo podemos testear nuestro código con el framework de test para Javascript JsTestDriven para ayudarnos a que nuestras aplicaciones js sean más robustas y flexibles a cambios. Además cabe destacar la gran facilidad con la que este framework prueba en diferentes navegadores. Recordemos que muchas veces el comportamiento de un navegador no es exáctamente igual al de otro (todos nos acordamos de IE…).
Nótese que este framework dispone de plugins para entornos de desarrollo como Eclipse e Intellij IDEA, donde el servidor se arranca y los test´s se ejecutan directamente desde el entorno. Aquí os dejo un pantallazo del plugin de Eclipse:
Espero que este tutorial os haya sido de ayuda. Un saludo.
Miguel Arlandy
Twitter: @m_arlandy
Este ejemplo está desarrollado en un proyecto HTML5, Java WEB o PHP??