cypress-angular-unit-test
Installation
npm install -D cypress cypress-angular-unit-test
Add to your support file
// cypress/support/index.js
// core-js 3.*
require('core-js/es/reflect');
// core-js 2.*
require('core-js/es7/reflect');
require('cypress-angular-unit-test/support');
Webpack config
Create a new file webpack.config.ts
in cypress/plugins
folder.
You can find the file content here :
Cypress >= v7
npm install -D @cypress/webpack-dev-server html-webpack-plugin
Enable component testing in cypress.json
.
{
"component": {
"componentFolder": "src/app",
"testFiles": "**/*cy-spec.ts"
}
}
Configure cypress/plugins/index.js
to transpile Angular code.
const webpackConfig = require('./webpack.config');
const { startDevServer } = require('@cypress/webpack-dev-server');
module.exports = (on, config) => {
on('dev-server:start', (options) =>
startDevServer({
options,
webpackConfig,
}),
);
return config;
};
Run npx cypress open-ct
Cypress < v7
npm install -D @cypress/webpack-preprocessor
Enable experimental component testing mode in cypress.json
and point at the spec files. Usually they are alongside your application files in src
folder.
{
"experimentalComponentTesting": true,
"componentFolder": "src",
"testFiles": "**/*cy-spec.*"
}
Configure cypress/plugins/index.js
to transpile Angular code.
const wp = require('@cypress/webpack-preprocessor');
const webpackConfig = require('./webpack.config');
module.exports = (on, config) => {
const options = {
webpackConfig,
};
on('file:preprocessor', wp(options));
return config;
};
Run npx cypress open
Use
import { mount } from 'cypress-angular-unit-test';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
it('shows the input', () => {
// Init Angular stuff
initEnv(AppComponent);
// You can also :
// initEnv({declarations: [AppComponent]});
// initEnv({imports: [MyModule]});
// component + any inputs object
mount(AppComponent, { title: 'World' });
// use any Cypress command afterwards
cy.contains('Welcome to World!');
});
});
Examples
Use case | Description |
---|---|
Input | Test inject @Input() value |
Output | Test catching @Output() |
Bootstrap | Bootstrap integration with style : setConfig({ stylesheet: 'https://...}); |
Add style | Add custom style for testing : setConfig({ style: 'p {background-color: blue;}' }); |
HTML mount | Mount a component with html, don't forget to call detectChanges() after |
Image Snapshot | Mount a component and visual asserting |
Material | Material integration |
Prime NG | PrimeNG integration |
OnPush strategy | Component with changeDetection: ChangeDetectionStrategy.OnPush need call detectChanges() |
Directive | Test directive with mountHtml |
Pipe | Test pipe with mountHtml |
Stub service | Stub a service with Observable |
Only service | Test a service without a component |
Web Component | Test a custom element with shadow dom |
Assets | assets folder accessible by Cypress |
Async | Async test with cy.tick |
Routing | Test routing link |
Network | Test with http calls |
NGRX | NGRX store |
Code coverage
Integration test
- Install ngx-build-plus to extends the Angular CLI's build process and instrument the code
npm i -D ngx-build-plus
- Add webpack coverage config file coverage.webpack.js to cypress folder
module.exports = {
module: {
rules: [
{
test: /\.(js|ts)$/,
loader: 'istanbul-instrumenter-loader',
options: { esModules: true },
enforce: 'post',
include: require('path').join(__dirname, '..', 'src'),
exclude: [
/\.(e2e|spec)\.ts$/,
/node_modules/,
/(ngfactory|ngstyle)\.js/,
],
},
],
},
};
- Update
angular.json
to use ngx-build with extra config
"serve": {
"builder": "ngx-build-plus:dev-server",
"options": {
"browserTarget": "cypress-angular-coverage-example:build",
"extraWebpackConfig": "./cypress/coverage.webpack.js"
},
}
- Instrument JS files with istanbul for code coverage reporting
npm i -D istanbul-instrumenter-loader
- Add cypress code coverage plugin
npm install -D @cypress/code-coverage
- Then add the code below to your supportFile and pluginsFile
// cypress/support/index.js
import '@cypress/code-coverage/support';
// cypress/plugins/index.js
module.exports = (on, config) => {
require('@cypress/code-coverage/task')(on, config);
return config;
};
source : https://github.com/skylock/cypress-angular-coverage-example
Unit test
- Instrument JS files with istanbul for code coverage reporting
npm i -D istanbul-instrumenter-loader
- In your
cypress/plugins/cy-ts-preprocessor.ts
add this rule
rules: [
{
test: /\.(js|ts)$/,
loader: 'istanbul-instrumenter-loader',
options: { esModules: true },
enforce: 'post',
include: path.join(__dirname, '../..', 'src'),
exclude: [/\.(e2e|spec)\.ts$/, /node_modules/, /(ngfactory|ngstyle)\.js/],
},
];
Report
You can find the HTML report at coverage/lcov-report/index.html
Working
I have successfully used this mounting approach to test components in other frameworks.
- cypress-vue-unit-test
- cypress-react-unit-test
- cypress-cycle-unit-test
- cypress-svelte-unit-test
- cypress-angular-unit-test
- cypress-hyperapp-unit-test
- cypress-angularjs-unit-test
Debugging
You can turn on debugging log by setting environment variable :
// Unix
export DEBUG="cypress-angular-unit-test,cypress:webpack:stats"
// PowerShell
$env:DEBUG="cypress-angular-unit-test,cypress:webpack:stats"
Development
This project only transpiles the library, to see it in action:
- Install dependencies
npm i
- Compile the library
npm run build
- Open Cypress with
npx cypress open
Pick any component test spec file to run