« Back
in javascript angularjs atom unit-tests karma jasmine read.

Tests unitarios de JavaScript en 5 min con Atom.

Recientemente, en un podcast sobre javascript que sigo, mencionaron un plugin para Atom1 llamado Wallaby.js con el que se podían hacer tests unitarios de manera indolora y, después de probarlo, la verdad es que la experiencia es 100% recomendable, el gif que viene a continuación habla por sí solo.

wallaby

Efectivamente, es lo que estás pensando, el test se ejecuta en tiempo real, mientras lo escribes, increíblemente útil!

Al turrón

Para mi caso en particular como FrontEnd, me interesaba especialmente el tema de hacer tests unitarios para AngularJS2, aunque éste tutorial puede ser igual de válido para NodeJS y en general cualquier tecnología JavaScript. De hecho, estás invitado oficialmente a clonarte el repositorio de ejemplo que tengo preparado para el tutorial, para poder ver la magia de wallaby en acción.

Instalación

Tan sencillo como ir al buscador de packages de atom y descargar atom-wallaby.

install

Configuración

Hay varias opciones de configuración, entre ellas, tener un archivo .wallabyrc en el directorio del proyecto o en cambio un wallaby.json. Personalmente prefiero este último porque es un simple JSON y Atom lo puede interpretar como tal, quedaría algo así.

wallaby.json

{  
  "files": [
    "node_modules/angular/angular.js",
    "node_modules/angular-mocks/angular-mocks.js",
    "js/**/*.js"
  ],
  "tests": [
    "test/**/*.coffee"
  ]
}

Independientemente de cuál sea el formato que eligamos para nuestra configuración, el siguiente paso es imprescindible: decirle a wallaby que éste es nuestro fichero de configuración.

config

En este paso tengo que hacer un alto para mencionar una singularidad que me ha parecido increíble... a wallaby le da igual que los tests sean CoffeeScript o JavaScript nativo. Esto es impresionante en sí mismo porque para hacer algo equiparable en Karma (el framework por defecto para testear AngularJS) se requieren librerías adicionales e incluso un preprocesador para precompilar el código .coffee a .js para que luego los tests puedan ser interpretados, TODO esto lo hace wallaby él solito, sin ayuda.

Código

index.spec.coffee

describe 'assembly-timer tests', =>

    scope = {}
    ctrl = {}

    beforeEach module 'MyApp'

    beforeEach inject ($controller, $rootScope) =>
        scope = $rootScope.$new()
        ctrl = $controller 'TimerCtrl', $scope: scope
        spyOn scope, '$broadcast'

    it 'variable inicialization', =>
        expect(scope.blink).toBe(true)
        expect(scope.fontSize).toEqual({})
        expect(scope.timerColor).toEqual({})
        expect(scope.deadlineMillis).toBe(0)
        expect(scope.timerRunning).toBe(false)

    it 'time over function', =>
        expect(scope.timerColor.color).toBeUndefined()
        scope.timeOver()
        expect(scope.timerColor.color).toBe('blinking-end')
        scope.blink = false
        scope.timeOver()
        expect(scope.timerColor.color).toBe('end')

    it 'change size function', =>
        for number in [10..100]
            scope.changeSize(number)
            expect(scope.fontSize).toEqual({'font-size': number + 'px'})

    it 'start timer event', =>
        scope.startTimer(100)
        expect(scope.$broadcast).toHaveBeenCalledWith('timer-start')
        expect(scope.timerRunning).toBe(true)
        expect(scope.deadlineMillis).toBe(6000000)

    it 'stop timer event', =>
        scope.stopTimer()
        expect(scope.$broadcast).toHaveBeenCalledWith('timer-stop')
        expect(scope.timerColor).toEqual({})
        expect(scope.deadlineMillis).toEqual(0)
        expect(scope.timerRunning).toBe(false)

    it 'timer tick event', =>
        scope.startTimer(100)
        scope.$broadcast('timer-tick')
        expect(scope.$broadcast).toHaveBeenCalledWith('timer-tick')
        expect(scope.timerRunning).toBe(true)
        expect(scope.deadlineMillis).toBe(6000000)

Como habréis observado, el código de los tests de mi proyecto es CoffeeScript, no por nada en particular, sino porque en este caso concreto estaba haciendo pruebas de concepto y me pareció que IMHO3 era más legible y menos lioso en este lenguaje. Si en este punto os habéis asustado un poco aquí tenéis el mismo test pero en javascript nativo ;)

De hecho, no puedo pasar por alto el hecho de que wallaby es sumamente flexible, ya que yo estoy utilizando el dúo Karma & Jasmine, mientras que en el artículo original 4 se utiliza Mocha & Chai.

Resultado

Simple, elegante, increíble.

result

Ejecutamos npm test en la consola y obtenemos el mismo resultado de los tests en el navegador abierto por Karma.

karma

Espero que éste pequeño post os sea de gran ayuda y que a partir de ahora disfrutéis tanto como yo haciendo vuestros tests unitarios, no olvidéis compartir el post en las redes sociales y dejar algo de feedback en los comentarios!

Sed felices ;)


PD: Sin que sirva de precedente, he decidido escribir este post en español debido a la escasa documentación que hay sobre este tema en nuestro idioma. Según el feedback que tenga el post, puede que me plantee el cambio a la hora de crear contenido, aunque eso sí, el idioma por excelencia de las Information Technologies siempre será el inglés :P

  1. En la página oficial de wallaby están disponibles también versiones del plugin para WebStorms y para Visual Studio, a un módico precio eso sí.

  2. Para angular en concreto es posible que hagan falta algunas librerías adicionales, como karma o jasmine, en el proyecto de ejemplo están todas incluidas y el resultado de los tests se puede ver en la consola, en el navegador que abre Karma cuando se ejecuta y también en el propio wallaby.

  3. In My Humble Opinion ;)

  4. El artículo original aquí

comments powered by Disqus