Skip to content

Commit

Permalink
feat(testing): add disableJestRuntime option to @nx/jest/plugin to sp…
Browse files Browse the repository at this point in the history
…eed up target inference (#28522)

This PR adds a new `disableJestRuntime` option to `@nx/jest/plugin`. By
setting this to `true`, the inference plugin will not use `jest-config`
and `jest-runtime` to retrieve `outputs`, nor matching spec files when
`ciTargetName` is used. Instead, we'll use our own config loader and
glob/matcher to get both values for the inferred targets.

This speeds up computation quite a bit. With a large monorepo (800
projects, 75K files), the computation goes from 2m 41s to 35s, or ~78%
time reduction.

NOTE: This has no effect on existing projects and needs to be opted
into.


<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
  • Loading branch information
jaysoo authored Oct 31, 2024
1 parent 4014662 commit 178d93d
Show file tree
Hide file tree
Showing 5 changed files with 662 additions and 103 deletions.
5 changes: 4 additions & 1 deletion docs/generated/packages/jest/documents/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,16 @@ within the same workspace. In this case, you can configure the `@nx/jest/plugin`
"include": ["e2e/**/*"],
"options": {
"targetName": "e2e-local",
"ciTargetName": "e2e-ci"
"ciTargetName": "e2e-ci",
"disableJestRuntime": false
}
}
]
}
```

If you experience slowness from `@nx/jest/plugin`, then set `disableJestRuntime` to `true` to skip creating the Jest runtime. By disabling the Jest runtime, Nx will use its own utilities to find `inputs`, `outputs`, and test files for [Atomized targets](/ci/features/split-e2e-tasks). This can reduce computation time by as much as 80%.

### Splitting E2E Tests

If Jest is used to run E2E tests, you can enable [splitting the tasks](/ci/features/split-e2e-tasks) by file to get
Expand Down
5 changes: 4 additions & 1 deletion docs/shared/packages/jest/jest-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,16 @@ within the same workspace. In this case, you can configure the `@nx/jest/plugin`
"include": ["e2e/**/*"],
"options": {
"targetName": "e2e-local",
"ciTargetName": "e2e-ci"
"ciTargetName": "e2e-ci",
"disableJestRuntime": false
}
}
]
}
```

If you experience slowness from `@nx/jest/plugin`, then set `disableJestRuntime` to `true` to skip creating the Jest runtime. By disabling the Jest runtime, Nx will use its own utilities to find `inputs`, `outputs`, and test files for [Atomized targets](/ci/features/split-e2e-tasks). This can reduce computation time by as much as 80%.

### Splitting E2E Tests

If Jest is used to run E2E tests, you can enable [splitting the tasks](/ci/features/split-e2e-tasks) by file to get
Expand Down
1 change: 1 addition & 0 deletions packages/jest/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"prettier",
"jest",
"@jest/types",
"jest-runtime",
// require.resolve is used for these packages
"identity-obj-proxy"
]
Expand Down
328 changes: 328 additions & 0 deletions packages/jest/src/plugins/plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,334 @@ describe('@nx/jest/plugin', () => {
expect(results).toMatchSnapshot();
}
);

describe('disableJestRuntime', () => {
it('should create test and test-ci targets based on jest.config.ts', async () => {
mockJestConfig(
{
coverageDirectory: '../coverage',
testMatch: ['**/*.spec.ts'],
testPathIgnorePatterns: ['ignore.spec.ts'],
},
context
);
const results = await createNodesFunction(
['proj/jest.config.js'],
{
targetName: 'test',
ciTargetName: 'test-ci',
disableJestRuntime: true,
},
context
);

expect(results).toMatchInlineSnapshot(`
[
[
"proj/jest.config.js",
{
"projects": {
"proj": {
"metadata": {
"targetGroups": {
"E2E (CI)": [
"test-ci",
"test-ci--src/unit.spec.ts",
],
},
},
"root": "proj",
"targets": {
"test": {
"cache": true,
"command": "jest",
"inputs": [
"default",
"^production",
{
"externalDependencies": [
"jest",
],
},
],
"metadata": {
"description": "Run Jest Tests",
"help": {
"command": "npx jest --help",
"example": {
"options": {
"coverage": true,
},
},
},
"technologies": [
"jest",
],
},
"options": {
"cwd": "proj",
},
"outputs": [
"{workspaceRoot}/coverage",
],
},
"test-ci": {
"cache": true,
"dependsOn": [
"test-ci--src/unit.spec.ts",
],
"executor": "nx:noop",
"inputs": [
"default",
"^production",
{
"externalDependencies": [
"jest",
],
},
],
"metadata": {
"description": "Run Jest Tests in CI",
"help": {
"command": "npx jest --help",
"example": {
"options": {
"coverage": true,
},
},
},
"nonAtomizedTarget": "test",
"technologies": [
"jest",
],
},
"outputs": [
"{workspaceRoot}/coverage",
],
},
"test-ci--src/unit.spec.ts": {
"cache": true,
"command": "jest src/unit.spec.ts",
"inputs": [
"default",
"^production",
{
"externalDependencies": [
"jest",
],
},
],
"metadata": {
"description": "Run Jest Tests in src/unit.spec.ts",
"help": {
"command": "npx jest --help",
"example": {
"options": {
"coverage": true,
},
},
},
"technologies": [
"jest",
],
},
"options": {
"cwd": "proj",
},
"outputs": [
"{workspaceRoot}/coverage",
],
},
},
},
},
},
],
]
`);
});

it.each`
preset | expectedInput
${'<rootDir>/jest.preset.js'} | ${'{projectRoot}/jest.preset.js'}
${'../jest.preset.js'} | ${'{workspaceRoot}/jest.preset.js'}
`('should correct input from preset', async ({ preset, expectedInput }) => {
mockJestConfig(
{
preset,
coverageDirectory: '../coverage',
testMatch: ['**/*.spec.ts'],
testPathIgnorePatterns: ['ignore.spec.ts'],
},
context
);
const results = await createNodesFunction(
['proj/jest.config.js'],
{
targetName: 'test',
ciTargetName: 'test-ci',
disableJestRuntime: true,
},
context
);

expect(results[0][1].projects['proj'].targets['test'].inputs).toContain(
expectedInput
);
});

it.each`
testRegex
${'\\.*\\.spec\\.ts'}
${['\\.*\\.spec\\.ts']}
`(
'should create test-ci targets from testRegex config option',
async ({ testRegex }) => {
mockJestConfig(
{
coverageDirectory: '../coverage',
testRegex,
testPathIgnorePatterns: ['ignore.spec.ts'],
},
context
);
const results = await createNodesFunction(
['proj/jest.config.js'],
{
targetName: 'test',
ciTargetName: 'test-ci',
disableJestRuntime: true,
},
context
);

expect(results).toMatchInlineSnapshot(`
[
[
"proj/jest.config.js",
{
"projects": {
"proj": {
"metadata": {
"targetGroups": {
"E2E (CI)": [
"test-ci",
"test-ci--src/unit.spec.ts",
],
},
},
"root": "proj",
"targets": {
"test": {
"cache": true,
"command": "jest",
"inputs": [
"default",
"^production",
{
"externalDependencies": [
"jest",
],
},
],
"metadata": {
"description": "Run Jest Tests",
"help": {
"command": "npx jest --help",
"example": {
"options": {
"coverage": true,
},
},
},
"technologies": [
"jest",
],
},
"options": {
"cwd": "proj",
},
"outputs": [
"{workspaceRoot}/coverage",
],
},
"test-ci": {
"cache": true,
"dependsOn": [
"test-ci--src/unit.spec.ts",
],
"executor": "nx:noop",
"inputs": [
"default",
"^production",
{
"externalDependencies": [
"jest",
],
},
],
"metadata": {
"description": "Run Jest Tests in CI",
"help": {
"command": "npx jest --help",
"example": {
"options": {
"coverage": true,
},
},
},
"nonAtomizedTarget": "test",
"technologies": [
"jest",
],
},
"outputs": [
"{workspaceRoot}/coverage",
],
},
"test-ci--src/unit.spec.ts": {
"cache": true,
"command": "jest src/unit.spec.ts",
"inputs": [
"default",
"^production",
{
"externalDependencies": [
"jest",
],
},
],
"metadata": {
"description": "Run Jest Tests in src/unit.spec.ts",
"help": {
"command": "npx jest --help",
"example": {
"options": {
"coverage": true,
},
},
},
"technologies": [
"jest",
],
},
"options": {
"cwd": "proj",
},
"outputs": [
"{workspaceRoot}/coverage",
],
},
},
},
},
},
],
]
`);
}
);
});
});

function mockJestConfig(config: any, context: CreateNodesContext) {
Expand Down
Loading

0 comments on commit 178d93d

Please sign in to comment.