Skip to content

Commit

Permalink
feat(jest-core): Add perfStats to surface test setup overhead (#14622)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattkubej committed Nov 6, 2023
1 parent d89bdaf commit 4fedfbd
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- `[jest-config]` [**BREAKING**] Add `mts` and `cts` to default `moduleFileExtensions` config ([#14369](https://github.com/facebook/jest/pull/14369))
- `[jest-config]` [**BREAKING**] Update `testMatch` and `testRegex` default option for supporting `mjs`, `cjs`, `mts`, and `cts` ([#14584](https://github.com/jestjs/jest/pull/14584))
- `[@jest/core]` [**BREAKING**] Group together open handles with the same stack trace ([#13417](https://github.com/jestjs/jest/pull/13417), & [#14543](https://github.com/jestjs/jest/pull/14543))
- `[@jest/core]` Add `perfStats` to surface test setup overhead ([#14622](https://github.com/jestjs/jest/pull/14622))
- `[@jest/core, @jest/test-sequencer]` [**BREAKING**] Exposes `globalConfig` & `contexts` to `TestSequencer` ([#14535](https://github.com/jestjs/jest/pull/14535), & [#14543](https://github.com/jestjs/jest/pull/14543))
- `[jest-environment-jsdom]` [**BREAKING**] Upgrade JSDOM to v22 ([#13825](https://github.com/jestjs/jest/pull/13825))
- `[@jest/fake-timers]` [**BREAKING**] Upgrade `@sinonjs/fake-timers` to v11 ([#14544](https://github.com/jestjs/jest/pull/14544))
Expand Down
15 changes: 12 additions & 3 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2080,13 +2080,22 @@ This option allows the use of a custom results processor. This processor must be
"column": number,
"line": number
},
"duration": number | null
"duration": number | null,
"startAt": epoch | null
},
...
],
"perfStats": {
"start": epoch,
"end": epoch
"end": epoch,
"loadTestEnvironmentEnd": epoch,
"loadTestEnvironmentStart": epoch,
"runtime": number,
"setupAfterEnvEnd": epoch,
"setupAfterEnvStart": epoch,
"setupFilesEnd": epoch,
"setupFilesStart": epoch,
"slow": boolean,
"start": epoch
},
"testFilePath": absolute path to test file,
"coverage": {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const jestAdapter = async (
}
});

const setupAfterEnvStart = Date.now();
for (const path of config.setupFilesAfterEnv) {
const esm = runtime.unstable_shouldLoadAsEsm(path);

Expand All @@ -83,6 +84,7 @@ const jestAdapter = async (
runtime.requireModule(path);
}
}
const setupAfterEnvEnd = Date.now();
const esm = runtime.unstable_shouldLoadAsEsm(testPath);

if (esm) {
Expand All @@ -91,9 +93,15 @@ const jestAdapter = async (
runtime.requireModule(testPath);
}

const setupAfterEnvPerfStats = {
setupAfterEnvEnd,
setupAfterEnvStart,
};

const results = await runAndTransformResultsToJestFormat({
config,
globalConfig,
setupAfterEnvPerfStats,
testPath,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,13 @@ export const initialize = async ({
export const runAndTransformResultsToJestFormat = async ({
config,
globalConfig,
setupAfterEnvPerfStats,
testPath,
}: {
config: Config.ProjectConfig;
globalConfig: Config.GlobalConfig;
testPath: string;
setupAfterEnvPerfStats: Config.SetupAfterEnvPerfStats;
}): Promise<TestResult> => {
const runResult: Circus.RunResult = await run();

Expand Down Expand Up @@ -189,6 +191,7 @@ export const runAndTransformResultsToJestFormat = async ({
location: testResult.location,
numPassingAsserts: testResult.numPassingAsserts,
retryReasons: testResult.retryReasons,
startAt: testResult.startedAt,
status,
title: testResult.testPath[testResult.testPath.length - 1],
};
Expand All @@ -215,15 +218,21 @@ export const runAndTransformResultsToJestFormat = async ({

await dispatch({name: 'teardown'});

const emptyTestResult = createEmptyTestResult();

return {
...createEmptyTestResult(),
...emptyTestResult,
console: undefined,
displayName: config.displayName,
failureMessage,
numFailingTests,
numPassingTests,
numPendingTests,
numTodoTests,
perfStats: {
...emptyTestResult.perfStats,
...setupAfterEnvPerfStats,
},
testExecError,
testFilePath: testPath,
testResults: assertionResults,
Expand Down
1 change: 1 addition & 0 deletions packages/jest-circus/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ export const makeSingleTestResult = (
location,
numPassingAsserts: test.numPassingAsserts,
retryReasons: test.retryReasons.map(_getError).map(getErrorStack),
startedAt: test.startedAt,
status,
testPath: Array.from(testPath),
};
Expand Down
9 changes: 9 additions & 0 deletions packages/jest-runner/src/runTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ async function runTestInternal(
const docblockPragmas = docblock.parse(docblock.extract(testSource));
const customEnvironment = docblockPragmas['jest-environment'];

const loadTestEnvironmentStart = Date.now();
let testEnvironment = projectConfig.testEnvironment;

if (customEnvironment) {
Expand Down Expand Up @@ -169,6 +170,7 @@ async function runTestInternal(
testPath: path,
},
);
const loadTestEnvironmentEnd = Date.now();

if (typeof environment.getVmContext !== 'function') {
console.error(
Expand Down Expand Up @@ -213,6 +215,7 @@ async function runTestInternal(

const start = Date.now();

const setupFilesStart = Date.now();
for (const path of projectConfig.setupFiles) {
const esm = runtime.unstable_shouldLoadAsEsm(path);

Expand All @@ -225,6 +228,7 @@ async function runTestInternal(
}
}
}
const setupFilesEnd = Date.now();

const sourcemapOptions: sourcemapSupport.Options = {
environment: 'node',
Expand Down Expand Up @@ -329,8 +333,13 @@ async function runTestInternal(
const end = Date.now();
const testRuntime = end - start;
result.perfStats = {
...result.perfStats,
end,
loadTestEnvironmentEnd,
loadTestEnvironmentStart,
runtime: testRuntime,
setupFilesEnd,
setupFilesStart,
slow: testRuntime / 1000 > projectConfig.slowTestThreshold,
start,
};
Expand Down
12 changes: 12 additions & 0 deletions packages/jest-test-result/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ export const buildFailureTestResult = (
openHandles: [],
perfStats: {
end: 0,
loadTestEnvironmentEnd: 0,
loadTestEnvironmentStart: 0,
runtime: 0,
setupAfterEnvEnd: 0,
setupAfterEnvStart: 0,
setupFilesEnd: 0,
setupFilesStart: 0,
slow: false,
start: 0,
},
Expand Down Expand Up @@ -155,7 +161,13 @@ export const createEmptyTestResult = (): TestResult => ({
openHandles: [],
perfStats: {
end: 0,
loadTestEnvironmentEnd: 0,
loadTestEnvironmentStart: 0,
runtime: 0,
setupAfterEnvEnd: 0,
setupAfterEnvStart: 0,
setupFilesEnd: 0,
setupFilesStart: 0,
slow: false,
start: 0,
},
Expand Down
6 changes: 6 additions & 0 deletions packages/jest-test-result/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,13 @@ export type TestResult = {
openHandles: Array<Error>;
perfStats: {
end: number;
loadTestEnvironmentEnd: number;
loadTestEnvironmentStart: number;
runtime: number;
setupAfterEnvEnd: number;
setupAfterEnvStart: number;
setupFilesEnd: number;
setupFilesStart: number;
slow: boolean;
start: number;
};
Expand Down
1 change: 1 addition & 0 deletions packages/jest-types/src/Circus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ export type TestResult = {
*/
failing?: boolean;
invocations: number;
startedAt?: number | null;
status: TestStatus;
location?: {column: number; line: number} | null;
numPassingAsserts: number;
Expand Down
5 changes: 5 additions & 0 deletions packages/jest-types/src/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,11 @@ export type ProjectConfig = {
workerIdleMemoryLimit?: number;
};

export type SetupAfterEnvPerfStats = {
setupAfterEnvStart: number;
setupAfterEnvEnd: number;
};

export type Argv = Arguments<
Partial<{
all: boolean;
Expand Down
1 change: 1 addition & 0 deletions packages/jest-types/src/TestResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Callsite = {
export type AssertionResult = {
ancestorTitles: Array<string>;
duration?: number | null;
startAt?: number | null;
/**
* Whether [`test.failing()`](https://jestjs.io/docs/api#testfailingname-fn-timeout)
* was used.
Expand Down

0 comments on commit 4fedfbd

Please sign in to comment.