Pichí, de etringita

¿Sigues con ganas de aprender un poco más sobre tests unitarios en WordPress? Genial, porque precisamente hoy dejamos atrás el mundo PHP y saltamos al front-end y, con ello, al testing de JavaScript. Emocionante, ¿eh? ? En la entrada de hoy veremos un par de frameworks para el test unitario de código JavaScript y te explicaré cómo puedes usarlos en WordPress. Además, como supongo que ya eres un experto en el tema de los tests unitarios ?, también compartiré un par de vídeos en YouTube que me encantaron y con los que aprenderás un montón.

Pero antes de empezar con JavaScript…

La solución al problema de la semana pasada con PHPUnit

En la entrada de PHPUnit te puse un pequeño problema que debías resolver:

Reescribe la función neliovat_get_iva para que cadenas de texto con un precio como por ejemplo (15,20, 1.000 y 3€, donde los separadores de miles son ., los de decimales son ,, no hay nunca espacios pero puede haber moneda al final) pase el test.

Recordemos que la función original era esta:

y que nuestro test era el siguiente:

Imagino que, como eres una buena persona y muy, muy trabajadora, has cumplido con tus obligaciones, ¿verdad? ? Venga, veamos cómo podemos solucionarlo.

La idea es que tenemos una cifra a la básicamente tenemos que quitarle la moneda (si la hubiera), los separadores de miles (si los hubiera) y cambiar la coma decimal por un punto (si la hubiera). Una vez tenemos hecho esto, podemos procesar la cadena de texto para convertirla en un número y, ahora sí, extraer el IVA. El resultado sería este:

que, como puedes ver, sí supera el test:

Test creado en PHPUnit pasado con éxito
¿Ves? Ahora el test que hemos creado con PHPUnit es superado sin ningún problema.

Frameworks de test JavaScript

Si bien para testear código PHP el rey indiscutible es PHPUnit, para JavaScript el abanico de posibilidades que tenemos es mucho más amplio. En stateofjs tenemos una comparativa super detallada de muchos de ellos:

Frameworks de test en JavaScript
Diferentes frameworks para realizar tests JavaScript (fuente).

Mocha

Mocha es uno de los frameworks de test que más tirada tienen a día de hoy. Se puede ejecutar tanto en un navegador como en un entorno nodejs. Entre sus funcionalidades, destacan los informes sobre el porcentaje de código testeado, el soporte para la integración continua o la capacidad de testear componentes asíncronos.

Mocha - Framework para el test de JavaScript
Uno de los frameworks más usados es Mocha.

Jasmine

Otro de los frameworks que tiene mucha fuerza a día de hoy es Jasmine. Tal y como puedes leer en su web, Jasmine es un framework que no necesita instanciar DOM, con una sintaxis limpia y clara con la que podrás escribir tests. Su documentación es muy extensa y te permite hacerte una idea rápida de cómo funciona.

Jasmine es un framework para el test de código JavaScript
Jasmine es otro framework para el test de código JavaScript.

Si estás dudando entre usar uno u otro, encontrarás un montón de entradas donde se comparan ambos frameworks (y otros más). Aunque yo creo que lo mejor es que los pruebes tú mismo y te decantes por el que te resulte más cómodo.

QUnit

Finalmente, quería mencionar uno de los veteranos en el mundo del test JavaScript: QUnit. Este framework nació precisamente con el objetivo de testear las librerías de jQuery (que seguro que has usado).

QUnit - El test de framework JavaScript creado por y para jQuery
QUnit es el test de framework JavaScript creado por y para jQuery.

Aunque me da la sensación que está perdiendo un poco de fuelle respecto a los otros competidores, no podía dejar de mencionar QUnit porque este es, precisamente, el que se usa en el core para testear los componentes JavaScript de WordPress. Es precisamente por ello que he decidido que merecía la pena dedicar un par de minutos a QUnit en lugar de a cualquier otro framework. Así pues, ¡veamos un primer ejemplo!

Preparando nuestro primer test en QUnit

Supongamos que tenemos la versión JavaScript de nuestra querida función nelio_get_vat en el fichero functions.js:

Imaginemos que queremos comprobar que se cumplen las mismas condiciones que en la versión PHP. Es decir, queremos que esta función calcule el 21% de una cantidad de dinero, independientemente de que ésta esté expresada como un entero, un número en coma flotante o una cadena de texto con separador de miles, comas y moneda.

El test lo podríamos escribir de la siguiente forma, en un fichero llamado, por ejemplo, tests.js:

Para ponerlo en marcha, tenemos que crear un pequeño HTML donde se incluya la librería QUnit, el/los ficheros JavaScript con las funciones que queremos testear y el fichero con la lista de tests:

Si ahora abrimos esta web en el navegador, el resultado es el siguiente:

Resultados de los tests QUnit
Resultados de los tests QUnit.

Como puedes ver, aunque la sintaxis y el lenguaje son diferentes, la mecánica es exactamente la misma que habíamos visto en la entrada anterior con PHP y PHPUnit.

Algunos consejos para ser más efectivos

Como acabamos de ver, la mecánica que hay detrás de los tests unitarios en JavaScript es exactamente la misma que hay en PHP. Y es que, en el fondo, da igual el lenguaje para el que estés escribiendo los tests; lo importante de verdad es querer realizar esos tests y ser lo más eficiente posible a la hora de hacerlo.

Según mi experiencia, lo que más cuesta es empezar; si nunca has testeado tu código de forma automática, es muy difícil saber qué tests hacer. ¿Estoy testeando los componentes importantes? ¿Estoy olvidando algún caso extremo? ¿Son comprensibles estos tests? ¿Mis tests se ejecutan lo suficientemente rápido? Todas estas preguntas son completamente normales y, de hecho, es positivo que te las hagas, porque indican que estás interesado en hacer bien tu trabajo.

Si dominas el inglés, he seleccionado un par de vídeos que (creo) pueden resultarte muy interesantes. El primero es este:

En este vídeo, Roy Osherove habla de buenas y malas prácticas a la hora de escribir tests para JavaScript (aunque, como te decía antes, los consejos son extrapolables a cualquier lenguaje y framework de test). Creo que merece muchísimo que dediques una horita de tu tiempo a verla, porque te ayudará a escribir mejores tests y te ahorrarás errores de novato. De hecho, yo ya la he visto múltiples veces; siempre que me surgen dudas escribiendo nuevos tests, ésta charla tiene las respuestas. De todas formas, como sé que quizás no tienes tiempo, voy a subrayar los puntos que, para mí, son más relevantes:

  • Un buen test unitario tiene tres pilares fundamentales (ver en el vídeo)
    1. Podemos confiar en él. Si el test te dice que todo está bien y no confías en su respuesta, estarás tentado de ir a comprobar que, sí, efectivamente está todo ben. O si te dice que está mal y no te fías puedes pensar que, «bah, a veces se equivoca, es algo de la configuración, seguro que está todo bien». Y si estás en ese punto, ¿para qué realizar tests?
    2. Se puede mantener. Los tests van a cambiar, porque tu código va a cambiar… así que sé limpio y ordenado, no escribas código de test que no se pueda adaptar a las necesidades.
    3. Es inteligible. Si un test falla, el programador querrá entender por qué está fallando. En otras palabras, necesitará leer el test, entender cuáles son los resultados que se estaban esperando y ver por qué su código no está superando el test. Si tus tests no son comprensibles será imposible para futuros programadores (entre los que puedes estar tú) saber cómo corregir un bug.
  • Los tests deben ser sencillos (ver en el vídeo). Cada vez que añades código a tu test aumentas las posibilidades de que sea el propio test el que falla, así que intenta que sea lo más sencillo posible. Sin bucles, sin muchos condicionales… pequeñas funciones de test que comprueban pequeñas funcionalidades de tu programa. Ni más, ni menos.
  • Usa nombres que sean comprensibles (ver en el vídeo). Esta es, quizás, la parte del vídeo que me gustó más: cómo dar nombres a los tests para que realmente se entienda lo que están testeando sin tener que mirar el código de test. Para que los tests sean realmente comprensibles tienen que definir tres conceptos:
    1. Unidad de trabajo (unit of work): aquello que estamos testeando. La clase WP_Post de WordPress, la función que calcula IVAs, el módulo de persistencia… lo que sea, pero que quede claro.
    2. Escenario: el contexto en el que estamos realizando el test. Hay funciones que siempre se comportan igual, otras que cambian en función de cómo se llaman. Por ejemplo, si guardamos una entrada que no existe, esperamos que ésta tenga un identificador nuevo. Pero si guardamos una entrada que ya existía, esperamos que el identificador sea el mismo de antes. Dada una entrada, pues, los contextos de test podrían ser «al crearla» o «al editarla y guardarla».
    3. Comportamiento esperado (expected behavior): cuál es el resultado que esperamos. Lo importante es enunciar el comportamiento esperado usando «should» or «shoudn’t«. Por ejemplo, si cuando guardo una entrada existente espero que el identificador no cambie, el test se podría enunciar de la siguiente forma: «Given a post (unidad de trabajo) that already exists in the database, when we save it using wp_post_save (escenario), its ID should be the same as before (expected behavior)»; es decir, «dada una entrada que existe en la base de datos, si la guardo con la función wp_post_save, su identificador debería ser el mismo de antes». El hecho de usar el tiempo condicional deja claro cuál es el objetivo, qué es lo que queremos. Si hubiéramos usado un tiempo indicativo («…su identificador es el mismo que antes») no nos queda claro si estamos enunciando el problema («el identificador es el mismo, pero debería ser diferente») o estamos enunciando el objetivo («debería ser diferente»).

El segundo vídeo está especialmente enfocado para aquellas personas que quieren testear su código y no saben por dónde empezar:

En el minuto 4:43, Rebecca nos enseña una pequeña aplicación para el navegador y muestra el «típico» código JavaScript que muchos programadores hubiéramos escrito para hacerla funcionar. El problema con el código presentado es que no se puede testear; las diferentes funcionalidades están mezcladas, confundiendo UI, comunicación con el servidor, estado de la aplicación; hay funciones anónimas vinculadas a eventos del DOM…

Un poco más adelante, la ponente expone una serie de guías para conseguir que nuestro código sea testeable y, de paso, más fácil de leer, comprender y mantener:

  • Usa constructores para crear instancias.
  • Permite que las cosas sean configurables.
  • Haz métodos sencillos
  • No mezcles las responsabilidades

Si continúas viendo el vídeo, verás cómo aplica estos principios en el ejemplo presentado en el inicio. En mi opinión, el resultado final es un código mucho más limpio y elegante.

Resumiendo

Realizar tests unitarios en JavaScript es exactamente lo mismo que hacerlo en cualquier otro lenguaje de programación. Lo que de verdad importa está en lo que se explica en los últimos vídeos enlazados: hay que escribir código sencillo que se pueda testear y hay que escribir tests sencillos y cortitos que se puedan entender. Si intentamos aplicar estas guías, los resultados mejorarán un montón.

En la próxima entrada te explicaré un ejemplo muy completo donde combinaremos los tests PHP y JavaScript. En concreto, pondremos a prueba llamadas AJAX, testeando la parte servidor y la parte cliente. ¡Nos vemos en unos días para cerrar el año por todo lo alto! ??

Imagen destacada de etringita.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

He leído y acepto la política de privacidad de Nelio Software

Tus datos personales se almacenarán en SiteGround y serán usados por Nelio Software con el único objetivo de publicar tu comentario aquí. Con el envío de este comentario, nos das el consentimiento expreso para ello. Escríbenos para acceder, rectificar, limitar o eliminar tus datos personales.