La importancia de los tests en Javascript

Cuando trabajamos con lenguajes dinámicos como Javascript los tests son mucho más importantes que en lenguajes estáticos. Ahora que he empezado a usar mas Javascript en la vida real y tener cosas más complejas que aplicaciones básicas con node.js o Knockout, mantener el código funcionando se hace más complicado y los tests más necesarios.

La principal razón por la que los tests son más necesarios se porque no hay una fase de compilación como tal. Esto provoca que no podamos detectar fallos hasta el momento de ejecutar la aplicación, pero sobre todo impide aprovechar las capacidades de análisis estático de un compilador moderno.

Si usamos un lenguaje estático como C#, el primer control de errores lo realiza el compilador. Para poder ejecutar la aplicación antes debe compilarse y, durante este proceso, el compilador es capaz de detectar infinidad de errores: variables no declaradas, signaturas de métodos incompatibles, comprobación de tipos de parámetros, restricciones de tipos en tipos genéricos, etc. Sin un compilador, todos estos errores no se descubrirán hasta el momento de ejecutar la aplicación.

Además, en general las herramientas disponibles no son tan completas como las que encontramos en .NET y el soporte que tienen para tareas habituales, como refactorizaciones sencillas (extraer parámetro, renombrar símbolo, etc.), es bastante limitado. Debido a esto, las refactorizaciones se realizan de forma manual, lo que puede provocar errores.

Otro factor a tener en cuenta es que, al aprovechar las características de un lenguaje dinámico todo se vuelve muy… dinámico. Por ejemplo, al usar literal objects estamos creando objetos cuya definición no está en ninguna parte, no hay una definición de la clase a la que acudir para ver qué propiedades o métodos tiene el objeto. En general esto no es problema si sólo creas ese tipo de objetos en un punto de la aplicación, pero como te descuides y empieces a crearlos en varios puntos…

También se da el caso de una función cuyos parámetros pueden ser de varios tipos y hacer cosas diferentes en función de los tipos recibidos. Un ejemplo muy claro es la función jQuery o $, cuyo primer argumento puede ser un string con un selector CSS o un HTMLElement.

Estas características tan dinámicas son muy potentes, pero a cambio pueden convertirse en complicadas de mantener rápidamente. El hecho de no declarar los tipos de los parámetros puede restar legilibidad al código y obliga a mantenerlo documentado. Cuando uso un lenguaje estático, casi nunca escribo un comentario porque entre los tipos y los nombres de las cosas, el código casi se documenta sólo. Sin embargo, al trabajar con Javascript acabo escribiendo más comentarios para poder indicar qué tipos de datos espera cada parámetro de una función, ya que si no lo hago la única forma de saber los tipos soportados es leer el código de función.

Todos estos factores hacen que el uso de test (unitarios, de aceptación, de integración, de lo que sea) se convierta en algo fundamental para poder mantener funcionando bases de código más o menos complejas. Aparte de ayudar al diseño (si usas TDD) o comprobar la validez del programas (con tests de aceptación), los tests actúan como red de seguridad al refactorizar y sirven de documentación para las distintas partes de la aplicación.

Dependiendo del tipo de tests a ejecutar, podemos usar distintas herramientas, como QUnit para test unitarios en el browser, Jasmine para aplicar BDD sin necesidad de usar un browser (con node.js) o Watin para crear tests de integración.

Por desgracia, la ejecución de tests en Javascript y, especialmente, su uso en un proceso de integración continua, no siempre es una tarea fácil. Además, hay que tener en cuenta que la implementación de Javascript en cada browser presenta algunas diferencias, como vimos hace poco con el tema del parsing de fechas. Esto hace que, para estar seguros de que todo funciona, debamos ejecutar los tests sobre varios browsers distintos, lo que supone una complejidad adicional.

Pese a estas complicaciones, sigo convencido de que merece la pena hacer un esfuerzo por testear el código Javascript porque se le saca bastante partido a los tests. Como decía en mi anterior post, cada vez hacemos aplicaciones más complejas en Javascipt y como tales debemos tratarlas.

Un comentario en “La importancia de los tests en Javascript

  1. Pingback: Testear Javascript con PhantomJS, QUnit y MSBuild

Comentarios cerrados.