Using Jest with Angular

Publiziert am 19 Juni 2018 unter Angular, Javascript, Jest, Testing von Daniel

Introduction

We are using Angular to build complex business application since the early version of AngularJS. While we love the framework and its rich ecosystem, we always struggled with the painful testing experience based on Jasmine and Karma. Our main pain points were the performance and the missing functionality to rerun only changed tests. With Jest, a testing platform from Facebook, these two points are solved in an elegant way and in addition it offers even more benefits.

This article shows how to configure your Angular application to integrate Jest. The article assumes that you are using an Angular CLI v6.0.x generated project from Angular v6.0.x. But it works too on earlier version of Angular projects.

Using Jest with Angular

This section describes the minimal configuration changes that are needed to run your tests with Jest.

Create a new Angular application and run the generated tests.

ng new myApp
cd myApp
ng test

Running the tests at this point is not necessary but it gives you a better comparison between the two test technologies.

The following steps have to be done to integrate Jest into your Angular app

Step 1: Install Jest dependencies

You need 3 development dependencies for Jest.

  • jest - Jest testing platform
  • jest-preset-angular - configuration preset for angular application
  • @types/jest. - Jest typings

Install the dependencies with the following command

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

In the package.json you should have the following 3 new entries:

"@types/jest": "^23.0.0",
"jest": "^23.1.0",
"jest-preset-angular": "^5.2.2"

Step 2: Replace Test Runner

In the scripts section of the package.json replace the following line

"test": "ng test"

with

"test": "jest"

Step 3: Basic Configuration

Fortunately for most cases only very few configuration is needed. The jest-preset-angular project extracted the common configuration options into the jest-preset-angular package that works for most of the cases. In order to use them, add this entry to the package.json

"jest": {
    "preset": "jest-preset-angular",
    "setupTestFrameworkScriptFile": "./src/setup-jest.ts"
}

Create the setup-jest.ts file in the src directory and add the following entry

import 'jest-preset-angular';

To run your tests with Jest type

npm test

Step 4: Remove Karma and Jasmine Dependencies (optional)

We recommend to remove all your jasmine and karma dependencies. Jest is based on Jasmine. Even though most of its functionality has been replaced and a lot of features were added, the API still looks very similar. This is an advantage when migrating from Jasmine to Jest but can lead to confusion during implementation when having both dependencies in the project.

In the package.json remove the following lines

"@types/jasmine": "~2.8.6",
"@types/jasminewd2": "~2.0.3",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~1.7.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^2.0.0",
"karma-jasmine": "~1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",

Uninstall the packages by typing

npm install

Step 5: Additional Configuration (optional)

In order to us the watch mode add the following line to the scripts section of the package.json

"test:watch": "jest —-watch"

The watch mode can be started by typing

npm run test:watch

To use the built-in code coverage reports add the following line to the scripts sections of the package.json

"test:cov": "jest —-coverage"

and start the report by typing

npm run test:cov

Using Jest with Angular and Nrwl Nx

Nrwl Extensions for Angular (aka Nrwl Nx) is an open source toolkit for enterprise application. We mainly use Nrwl Nx because of its “monorepo” approach. The CLI extensions and the linter rules help us to keep the same structure in all our projects.

You can find all information on how to integrate and use Nx in your project here.

Configuration changes

After installing Nrwl Nx the following steps need to be done

  • Define root directories
  • Define location of the tsconfig.spec.json file
  • Allow ts-jest to transform html files
  • Map absolute imports

Add the following lines in the package.json (in the jest section). Do not forget to adapt the location of your setup-jest.ts file

"roots": [
    "./apps",
    "./libs/"
],
"globals": {	  
    "ts-jest": {    
        "tsConfigFile": "./apps/angular6/tsconfig.spec.json"
    },
    "__TRANSFORM_HTML__": true
},
"moduleNameMapper": {
    "@myApp(.*)": "/libs/$1"
}

Technology Information

Jest

Jest promises “Delightful Javascript Testing”. Their key features are the following:

Zero configuration

Jest works out of the box with minimal setup or configuration. Jest was created by Facebook and is heavily used for testing React application. With only very small configuration changes it can be easily used in any Angular app.

Performance

Jest parallelises test runs across workers to maximise performance. This together with the fact that Jest does not require a browser and only runs tests that are affected by current code changes improves the performance.

Testing platform

Jest is neither a framework nor a library but a testing platform. An assertion library, a test runner and a mocking library are already integrated for example.

Watch mode

Jest provides an immersive watch mode. For example it runs only tests that have changed since the last run. In addition the user can filter the tests with regex patterns. With the newest version of JEST (v23.0) it is even possible to write plugins for the watch mode and define custom actions.

Error messages

Jest provides meaningful(er) error messages and uses color to make the test output more user friendly.

Built-in code coverage reports

Without any additional setup or library Jest creates code coverage reports from the entire projects, including untested files

Snapshot testing

Snapshot tests can be used to make sure your UI does not change unexpectedly. The tests take screenshots and compare them to reference images.

Jest-Preset-Angular

The jest-angular-preset project defines a preset of Jest configuration for Angular projects. The project extracted the common configuration options that should just work for most cases. If you have a special environment setup and/or if you need specific values in your configuration then you can overwrite every option manually.