Lesson 8

Setting up Tests with Jest and Cypress

Creating a new application with testing configured

PRO

Lesson Outline

Setting up Tests

We will cover setting up the application we will be building in this module step-by-step in another lesson, but I did want to first give you an overview of what it looks like to set up Jest and Cypress in your application. Getting everything set up and configured correctly can be tricky, but fortunately there are some tools available to us that will greatly simplify the process.

At the moment, an Angular application will come with Jasmine and Protractor set up by default. However, Protractor will soon be deprecated and the Angular team will be removing it from new Angular applications soon as well (this may have already happened by the time you are reading this). What we need to do is remove Jasmine/Protractor (if they are still included in the project) and set up Jest/Cypress.

I will give you a brief overview of the process now, but we will walk through this again later when we create the application. Feel free to just use this as a reference for later, or just to give you the basic idea now.

First, to install Cypress and remove Protractor we can use the schematic maintained by Cypress:

ng add @cypress/schematic

To add Jest, we can use the Briebug schematic:

ng add @briebug/jest-schematic

and set the following configuration options in jest.config.js:

module.exports = {
  moduleNameMapper: {
    '@core/(.*)': '<rootDir>/src/app/core/$1',
  },
  preset: 'jest-preset-angular',
  setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
  testPathIgnorePatterns: ['<rootDir>/cypress/'],
};

We don't want Jest to try and run the Cypress spec files, so we add it to the testPathIgnorePatterns.

Running Tests

In order to run all of the unit tests in the application you just need to run the following command:

npm test

NOTE: This is a bug that may have already been fixed, but if you get an error that says:

Schema validation failed with the following errors:
  Data path "/assets/0" must be string.

Make sure to update the "test" entry in your angular.json file to reflect the following (note that we have turned assets into an array of strings):

        "test": {
          "builder": "@angular-builders/jest:run",
          "options": {
            "tsConfig": "tsconfig.spec.json",
            "styles": [],
            "scripts": [],
            "assets": ["src/favicon.ico", "src/assets"]
          },
          "configurations": {
            "ci": {
              "progress": false,
              "watch": false
            }
          }
        },

Another thing to watch our for if you are using VS Code is that it might not recognise the types properly for Jest (it will only match against Jasmine types). If you find that Jest specific types are failing, you can add "types": ['jest'] manually to your root tsconfig.json file:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": ["es2018", "dom"],
    "types": ["jest"]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

If you want to "watch" your tests (i.e. Jest will automatically rerun tests when you save) you will need to call the ng test command directly and supply the --watch flag:

ng test --watch

If you want this to just be your default for tests, you can update the test script in package.json:

"test": "ng test --watch-all",

To run the E2E tests, you will need to run this command:

npm run e2e

This will launch the Cypress application. Once the Cypress application launches, you will be able to select which tests you want to run. If you get an error like this:

No version of Cypress is installed in: /Users/joshuamorony/Library/Caches/Cypress/10.2.0/Cypress.app

Please reinstall Cypress by running: cypress install

Just run the recommended command to install the appropriate version of Cypress:

cypress install

If you do not have cypress installed globally (i.e. the command above doesn't work) you can run:

npx cypress install

NOTE: If this is the first time you have launched Cypress it may take some time for the application to be verified which might time out the tests. If that happens, just run the command again. Keep in mind that the test should run successfully, but it will fail because the default test is looking for content that does not exist in our Ionic application. This is fine.

That's all there is to it! Of course, we don't really have any interesting tests in the empty project, but we will get to that.

Summary

Although it is often still necessary to configure a few things manually, the schematics make this whole process rather painless.