Binary Coffee

Configurando jest en Angular

angular typescript test jest

Por qué utilizar Jest en Angular

Si eres de aquellos que lleva algún tiempo por el mundillo de Angular, seguramente ya has escuchado sobre Jest y probablemente tienes la misma duda que tuve en su momento sobre si migrar o no a Jest, sumado además a ese pequeño e insuperable miedo de salir de nuestra zona de confort y probar nuevas cosas más allá de las que estamos acostumbrados. Pues a continuación te muestro desde mi experiencia, cuales son las razones por las que deberías empezar a utilizar Jest y dejar atras Jasmine+Karma, que es la suite de pruebas que Angular nos instala y configura por defecto al crear un proyecto nuevo.

El artículo va principalmente dirigido a esos proyectos que en el futuro pueden convertirse en algo grande y donde la cantidad de pruebas puede ser grande también en consecuencia. No es para ti el artículo, si el proyecto es pequeño o si simplemente ni siquiera usas pruebas automática al código. Que si eres del último grupo, te recomiendo que empieces ya a usar pruebas, que estamos en 2020.

A continuación las 6 razones por las que utilizo Jest:

  • Rapidez para ejecutar las pruebas

    Es uno de los principales motivos por los que debería cambiar a Jest. Desde mi experiencia personal puedo decir que Jest es alrededor de 5 veces más rápido. En uno de los últimos proyectos en los que estuve involucrado con una suma total de alrededor de 600 test unitarios en el frontend, tomaba cerca de 5 minutos correr los test con Jasmine+Karma. Esto cambió cuando migramos a Jest, donde el tiempo bajó a 1 minuto aproximadamente. Esto sin lugar a dudas se agradece, sobretodo en proyectos con semejante cúmulo de pruebas.

  • Errores más descriptivos

    Este es otro de los puntos que más me golpeó con Jasmine+Karma. Incontable el tiempo perdido tratando de arreglar pruebas que fallaban, para al final darme cuenta que por algún extraño motivo, la prueba anterior hacía que la siguiente fallara. Para nada he tenido este problema en Jest.

  • Reducir dependencias en el proyecto

    Aunque más adelante en el artículo van a reemplazar las dependencias de Jasmine+Karma por las de Jest, les comento que los primeros cuentan con 9 dependencias a diferencias de solo 4 dependencias que son necesarias con Jest.

  • No necesita integración con el navegador

    Pues si, resulta que para ejecutar los test con Karma, se hace necesario integrarlo con el navegador web (puede ser chrome o firefox) para ejecutar las pruebas, aunque se haga sin que nos demos cuenta. En este caso, Jest se basa en jsdom, librería que hace una abstracción virtual del dom del navegador, evitando que necesitemos utilizar un navegador web.

  • Cobertura del código

    Precisamente una de las tantas dependencias que desinstalaremos de Karma, es la que se encarga de esta función, mientras que en Jest esto ya se encuentra como parte de su librería.

  • Integración con Jasmine

    Aunque este tema no se tratará en el artículo, es otra de las tantas facilidades que se pueden encontrar en Jest. Es posible, migrar todas esas pruebas que ya tienes previamente con Jasmine, suponiendo que como fue mi caso en algún momento, cuentes con más de 500 pruebas en tu aplicación.

Eliminar Karma y Jasmine del proyecto

Ejecutar la siguiente línea en un terminal, para desinstalar todas las dependencias de Karma+Jasmine:

$ npm uninstall karma karma-chrome-launcher karma-coverage-istanbul-reporter karma-jasmine karma-jasmine-html-reporter jasmine-core jasmine-spec-reporter @types/jasmine @types/jasminewd2

Eliminar el archivo karma.conf.js en la carpeta raíz.

Eliminar el archivo test.ts de la carpeta src y luego de esto, eliminar la línea donde este archivo es referenciado en el fichero de configuración de typescript tsconfig-spec.json que contiene el siguiente texto:

// tsconfig-spec.json
// Check the other changes commented in this file,
// you will need those for the next step
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "emitDecoratorMetadata": true, // Add this line HERE
    "outDir": "./out-tsc/spec",
    "types": [
      "jest", // change this from jasmine to jest
      "node"
    ]
  },
  "files": [
    "./test-setup.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.spec.ts",
    "src/**/*.d.ts"
  ]
}

Luego hay que ir al archivo angular.json y buscar la configuración de test y eliminarla, esta configuración debe estar dentro de la sección de architect, ver el siguiente ejemplo:

// angular.json
{
  ...
  "projects": {
    "vpn2go-frontend": {
      ...
      "architect": {
        ...
        "test": { // this section should be removed
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          }
        },
        ...
      }
    }
  },
  ...
}

Instalar y configurar Jest en el proyecto

Para instalar las dependencias de jest, ejecutar el siguiente comando:

$ npm install --save-dev jest @types/jest jest-preset-angular

Luego necesitamos crear y modificar algunos archivos de configuración en el proyecto.

Crear el archivo test-setup.ts en la raíz del proyecto y copiarle la siguiente línea de código:

import 'jest-preset-angular';

Actualizar la sección script en el archivo package.json y dejarla de la siguiente forma

// package.json
{
  ...
  "scripts": {
    ...
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cc": "jest --coverage",
    ...
  },
  ...
  "devDependencies": {
    ...
    "@types/jest": "^26.0.4",
    "jest": "^26.1.0",
    "jest-preset-angular": "^8.2.1",
    ...
  }
}

Crear el archivo de configuración de jest en la carpeta raíz con el nombre jest.config.js y copiarle lo siguiente:

// jest.config.js
module.exports = {
  testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
  transform: {
    '^.+\\.(ts|js|html)$': 'ts-jest'
  },
  moduleFileExtensions: ['ts', 'js', 'html'],
  coverageReporters: ['html', 'lcov'],
  preset: "jest-preset-angular",
  setupFilesAfterEnv: ['./test-setup.ts']
};

Recordar que en el caso de no ser un proyecto nuevo, hay que integrar jest con Jasmine, o si el proyecto no es tan grande, se pueden directamente actualizar los tests y utilizar las funciones y herramientas que brinda Jest.

Ejecutar los pruebas con Jest

Para correr las pruebas, pueden usarse los comandos creados anteriormente:

  • Correr las pruebas una vez

    npm test
    
  • Correr las pruebas y quedarse vigilando por cambios

    npm run test:watch
    
  • Correr las pruebas una vez y genera el coverage del proyecto

    npm run test:cc
    

Conclusiones

Espero que el artículo fuese de tu agrado y te ayude si estás tratando de migrar a Jest o si simplemente lo estás pensando. Sin más, no olvides dejar tu comentario y compartir el artículo.

Happy coding!

Opiniones