Do you ask yourself if there is a better testing framework for your Angular applications? Use Angular with Jest and make your tests simpler and faster! In this post we migrate an example project and discuss the main advantages I found.

Take a look at jestjs.io for all the benefits they try to offer. For me the following made me migrate:

  • Easy migration
  • Faster tests with JSDOM
  • Test watching and parallel tests
  • Snapshot testing

As an example we migrate the project from a previous post on Angular http interceptors to Jest. The complete code can be found on github here.

Migrate Karma to Jest

One of the pillars of the Jest pitch is “zero configuration”. Here are the steps I took and decide for yourself on this point.

npm install -D jest @types/jest @angular-builders/jest

And remove all jasmine and karma dependencies. Moreover remove the unused karma.conf.js file.

This would be zero configuration but in our angular.json file we specify the builder used for the test command. We need to change this to use Jest:

"test": {
    "builder": "@angular-builders/jest:run",
    "options": {
        "polyfills": "src/polyfills.ts",
        "tsConfig": "tsconfig.spec.json",
        "testMatch": [ 
            "**/__tests__/**/*.[t]s?(x)",
            "**/?(*.)+(spec).[t]s?(x)" 
        ]
    }
 },

Jest also ships with its own mocking and assertions utilities. We will not focus on this point here for the migration is backwards compatible with jasmine and karma. In the tsconfig.spec.json file we add jest to the types used in the tests.

{
    "extends": "./tsconfig.json",
    "compilerOptions": {
        "outDir": "./out-tsc/spec",
        "module": "commonjs",
        "target": "es5",
        "types": [
            "jest",
            "node"
        ],
        "emitDecoratorMetadata": true,
    },
    "files": [
        "src/polyfills.ts"
    ],
    "include": [
        "src/**/*.spec.ts",
        "src/**/*.d.ts"
    ]
}

With this in place our tests run!

Screenshot 2020 01 31 at 14.31.29 - ANGULAR WITH JEST

There is a warning of a missing jest.config.js file. We can add an empty file to fix this. This is also the config file where we can add additional configuration for Jest.

JSDOM

Jsdom is the standard environment configured for Jest to run your tests. The goal of the jsdom project is “to emulate enough of a subset of a web browser to be useful for testing and scraping real-world web applications”. This means it’s a lightweight and fast test runner.

For Karma a browser window is opened which takes a lot of time. Recognise the following screen?

Screenshot 2020 01 30 at 13.02.46 - ANGULAR WITH JEST

Test watching and parallel tests

Jest offers lots of developer oriented optimisations. It runs failed tests first and organises tests based on how long they run. So you’re waiting just the minimal amount of time for the results you need. Furthermore in watch mode only the tests run for files you are working on.

ng test --watch

Jest runs tests in parallel and ensures this is done in a reliable manner. It tries to use all available threads which lowers the total time needed. On your CI server you could have limited resources available. You might need to limit the number of threads there to avoid really slow tests.

ng test --runInBand       // Runs everything sequentially
or
ng test --maxWorkers=2    // Uses up to 2 threads

Read more about troubleshooting here.

Snapshot testing

Before Jest I found myself checking that specific elements are shown. See the following expect statement.

expect(rootElement.querySelector('spinner')).not.toBeNull();

With Jest we can make a snapshot of the complete component. This way other unexpected changes in the template make the test fail.

expect(fixture).toMatchSnapshot();

With this power comes responsibility. Keep your snapshots small for they can really slow down the tests. And think about what you are testing. One snapshot test does not test your whole component.

Hopefully you can now make use of all benefits of Angular with Jest. Happy Jesting!