Jest is an open source test runner created by Facebook. It has a lot of great features:
- Immersive watch mode for providing near instant feedback when developing tests.
- Snapshot testing for validating features.
- Great built-in reporter for printing out test results.
Setting up Jest
By default, Nx will use Jest when creating applications and libraries.
nx g @nrwl/web:app frontend
Adding Jest to an Existing Project
Add Jest to a project using the jest-project
generator from @nrwl/jest
.
First, install @nrwl/jest
, if not already installed using your preferred package manager.
npm install --save-dev @nrwl/jest
yarn add --dev @nrwl/jest
Once installed, run the jest-project
generator
nx g @nrwl/jest:jest-project --project=<project-name>
Hint: You can use the
--dry-run
flag to see what will be generated.
Replacing <project-name>
with the name of the project you're wanting to add Jest too.
Using Jest
Testing Applications
The recommended way to run/debug Jest tests via an editor
To run Jest tests via nx use
nx test frontend
Watching for Changes
Using the --watch
flag will run the tests whenever a file changes.
nx test frontend --watch
Snapshot Testing
Jest has support for Snapshot Testing, a tool which simplifies validating data. Check out the official Jest Documentation on Snapshot Testing.
Example of using snapshots:
describe('SuperAwesomFunction', () => {
it('should return the correct data shape', () => {
const actual = superAwesomFunction();
expect(actual).toMatchSnapshot();
});
});
When using snapshots, you can update them with the --updateSnapshot
flag, -u
for short.
By default, snapshots will be generated when there are not existing snapshots for the associated test.
nx test frontend -u
Snapshot files should be checked in with your code.
Performance in CI
Typically, in CI it's recommended to use nx affected --target=test --parallel=[# CPUs] -- --runInBand
for the best performance.
This is because each jest process creates a workers based on system resources, running multiple projects via nx and using jest workers will create too many process overall causing the system to run slower than desired. Using the --runInBand
flag tells jest to run in a single process.
Configurations
Jest
Primary configurations for Jest will be via the jest.config.ts
file that generated for your project. This file will extend the root jest.preset.js
file. Learn more about Jest configurations.
Nx
Nx Jest Plugin options can be configured via the project config file or via the command line flags.
Hint: Use
--help
to see all available optionsnx test <project-name> --help
Code Coverage
Enable code coverage with the --coverage
flag or by adding it to the executor options in the project configuration file.
By default, coverage reports will be generated in the coverage/
directory under projects name. i.e. coverage/apps/frontend
. Modify this directory with the --coverageDirectory
flag. Coverage reporters can also be customized with the --coverageReporters
flag.
coverageDirectory
andcoverageReporters
are configurable via the project configuration file as well.
Global setup/teardown with nx libraries
In order to use Jest's global setup/teardown functions that reference nx libraries, you'll need to register the TS path for jest to resolve the libraries. Nx provides a helper function that you can import within your setup/teardown file.
import { registerTsProject } from 'nx/src/utils/register';
const cleanupRegisteredPaths = registerTsProject('.', 'tsconfig.base.json');
import { yourFancyFunction } from '@some-org/my-util-library';
export default async function () {
yourFancyFunction();
}
// make sure to run the clean up!
cleanupRegisteredPaths();
When using @swc/jest and a global setup/teardown file, You'll have to set the global setup/teardown file to be transformed with ts-jest. For example, if your files are named global-setup.ts
and global-teardown.ts
, then you would need to add to your project level jest.config.ts
a new entry in the transformers object
export default {
transform: {
'global-(setup|teardown).ts': 'ts-jest',
// resest of the transformers
},
};