Setting up Tests with Jest and Cypress
Creating a new application with testing configured
PROModule Outline
- Source Code & Resources PRO
- Lesson 1: Introduction PUBLIC
- Lesson 2: Introduction to Test Driven Development PUBLIC
- Lesson 3: Testing Concepts PUBLIC
- Lesson 4: Jest and Cypress PRO
- Lesson 5: A Simple Unit Test PRO
- Lesson 6: A Simple E2E Test PRO
- Lesson 7: Introduction to Angular's TestBed PRO
- Lesson 8: Setting up Tests with Jest and Cypress PUBLIC
- Lesson 9: Test Development Cycle PRO
- Lesson 10: Setting up Cypress & Jest in an Ionic/Angular Project PRO
- Lesson 11: The First Tests PRO
- Lesson 12: Injected Dependencies & Spying on Function Calls PRO
- Lesson 13: Building out Core Functionality PRO
- Lesson 14: Testing Asynchronous Code PRO
- Lesson 15: Creating a Mock Backend PRO
- Lesson 16: Setting up the Server PRO
- Lesson 17: Testing Integration with a Server PRO
- Lesson 18: Testing Storage and Reauthentication PRO
- Lesson 19: Refactoring with Confidence PRO
- Lesson 20: Conclusion 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.