Skip to content

Commit

Permalink
feat: set global timeout in command line argument (#8456)
Browse files Browse the repository at this point in the history
  • Loading branch information
ert78gb authored and SimenB committed Jun 5, 2019
1 parent b4e07d4 commit 46f9a97
Show file tree
Hide file tree
Showing 16 changed files with 135 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@

- `[expect]` Highlight substring differences when matcher fails, part 1 ([#8448](https://github.com/facebook/jest/pull/8448))
- `[jest-cli]` Improve chai support (with detailed output, to match jest exceptions) ([#8454](https://github.com/facebook/jest/pull/8454))
- `[*]` Manage the global timeout with `--testTimeout` command line argument. ([#8456](https://github.com/facebook/jest/pull/8456))

### Fixes

Expand Down
1 change: 1 addition & 0 deletions TestUtils.ts
Expand Up @@ -55,6 +55,7 @@ const DEFAULT_GLOBAL_CONFIG: Config.GlobalConfig = {
testNamePattern: '',
testPathPattern: '',
testResultsProcessor: null,
testTimeout: 5000,
updateSnapshot: 'none',
useStderr: false,
verbose: false,
Expand Down
4 changes: 4 additions & 0 deletions docs/CLI.md
Expand Up @@ -301,6 +301,10 @@ Lets you specify a custom test runner.

Lets you specify a custom test sequencer. Please refer to the documentation of the corresponding configuration property for details.

### `--testTimeout=<number>`

Default timeout of a test in milliseconds. Default value: 5000.

### `--updateSnapshot`

Alias: `-u`. Use this flag to re-record every snapshot that fails during this test run. Can be used together with a test suite pattern or with `--testNamePattern` to re-record snapshots.
Expand Down
21 changes: 21 additions & 0 deletions e2e/__tests__/__snapshots__/timeouts.test.ts.snap
@@ -1,5 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`does not exceed the command line testTimeout 1`] = `
PASS __tests__/a-banana.js
✓ banana
`;

exports[`does not exceed the command line testTimeout 2`] = `
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites.
`;
exports[`does not exceed the timeout 1`] = `
PASS __tests__/a-banana.js
✓ banana
Expand All @@ -13,6 +26,14 @@ Time: <<REPLACED>>
Ran all test suites.
`;
exports[`exceeds the command line testTimeout 1`] = `
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites.
`;
exports[`exceeds the timeout 1`] = `
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Expand Down
50 changes: 50 additions & 0 deletions e2e/__tests__/timeouts.test.ts
Expand Up @@ -60,3 +60,53 @@ test('does not exceed the timeout', () => {
expect(wrap(summary)).toMatchSnapshot();
expect(status).toBe(0);
});

test('exceeds the command line testTimeout', () => {
writeFiles(DIR, {
'__tests__/a-banana.js': `
test('banana', () => {
return new Promise(resolve => {
setTimeout(resolve, 1000);
});
});
`,
'package.json': '{}',
});

const {stderr, status} = runJest(DIR, [
'-w=1',
'--ci=false',
'--testTimeout=200',
]);
const {rest, summary} = extractSummary(stderr);
expect(rest).toMatch(
/(jest\.setTimeout|jasmine\.DEFAULT_TIMEOUT_INTERVAL|Exceeded timeout)/,
);
expect(wrap(summary)).toMatchSnapshot();
expect(status).toBe(1);
});

test('does not exceed the command line testTimeout', () => {
writeFiles(DIR, {
'__tests__/a-banana.js': `
test('banana', () => {
return new Promise(resolve => {
setTimeout(resolve, 200);
});
});
`,
'package.json': '{}',
});

const {stderr, status} = runJest(DIR, [
'-w=1',
'--ci=false',
'--testTimeout=1000',
]);
const {rest, summary} = extractSummary(stderr);
expect(wrap(rest)).toMatchSnapshot();
expect(wrap(summary)).toMatchSnapshot();
expect(status).toBe(0);
});
Expand Up @@ -16,7 +16,12 @@ import {
buildSnapshotResolver,
} from 'jest-snapshot';
import throat from 'throat';
import {addEventHandler, dispatch, ROOT_DESCRIBE_BLOCK_NAME} from '../state';
import {
addEventHandler,
dispatch,
getState as getRunnerState,
ROOT_DESCRIBE_BLOCK_NAME,
} from '../state';
import {getTestID} from '../utils';
import run from '../run';
import globals from '..';
Expand All @@ -42,6 +47,10 @@ export const initialize = ({
testPath: Config.Path;
parentProcess: Process;
}) => {
if (globalConfig.testTimeout) {
getRunnerState().testTimeout = globalConfig.testTimeout;
}

const mutex = throat(globalConfig.maxConcurrency);

Object.assign(global, globals);
Expand Down
4 changes: 4 additions & 0 deletions packages/jest-cli/src/cli/args.ts
Expand Up @@ -622,6 +622,10 @@ export const options = {
'provided: `<rootDir>/path/to/testSequencer.js`',
type: 'string' as 'string',
},
testTimeout: {
description: 'This option sets the default timeouts of test cases.',
type: 'number' as 'number',
},
testURL: {
description: 'This option sets the URL for the jsdom environment.',
type: 'string' as 'string',
Expand Down
1 change: 1 addition & 0 deletions packages/jest-config/src/ValidConfig.ts
Expand Up @@ -113,6 +113,7 @@ const initialOptions: Config.InitialOptions = {
testResultsProcessor: 'processor-node-module',
testRunner: 'jasmine2',
testSequencer: '@jest/test-sequencer',
testTimeout: 5000,
testURL: 'http://localhost',
timers: 'real',
transform: {
Expand Down
Expand Up @@ -168,6 +168,16 @@ exports[`testPathPattern <regexForTestFiles> ignores invalid regular expressions
exports[`testPathPattern --testPathPattern ignores invalid regular expressions and logs a warning 1`] = `"<red> Invalid testPattern a( supplied. Running all tests instead.</>"`;
exports[`testTimeout should throw an error if timeout is a negative number 1`] = `
"<red><bold><bold>● <bold>Validation Error</>:</>
<red></>
<red> Option \\"<bold>testTimeout</>\\" must be a natural number.</>
<red></>
<red> <bold>Configuration Documentation:</></>
<red> https://jestjs.io/docs/configuration.html</>
<red></>"
`;
exports[`watchPlugins throw error when a watch plugin is not found 1`] = `
"<red><bold><bold>● <bold>Validation Error</>:</>
<red></>
Expand Down
16 changes: 16 additions & 0 deletions packages/jest-config/src/__tests__/normalize.test.js
Expand Up @@ -1562,3 +1562,19 @@ describe('displayName', () => {
},
);
});

describe('testTimeout', () => {
it('should return timeout value if defined', () => {
console.warn.mockImplementation(() => {});
const {options} = normalize({rootDir: '/root/', testTimeout: 1000}, {});

expect(options.testTimeout).toBe(1000);
expect(console.warn).not.toHaveBeenCalled();
});

it('should throw an error if timeout is a negative number', () => {
expect(() =>
normalize({rootDir: '/root/', testTimeout: -1}, {}),
).toThrowErrorMatchingSnapshot();
});
});
1 change: 1 addition & 0 deletions packages/jest-config/src/index.ts
Expand Up @@ -149,6 +149,7 @@ const groupOptions = (
testPathPattern: options.testPathPattern,
testResultsProcessor: options.testResultsProcessor,
testSequencer: options.testSequencer,
testTimeout: options.testTimeout,
updateSnapshot: options.updateSnapshot,
useStderr: options.useStderr,
verbose: options.verbose,
Expand Down
10 changes: 10 additions & 0 deletions packages/jest-config/src/normalize.ts
Expand Up @@ -789,6 +789,16 @@ export default function normalize(
value = oldOptions[key];
break;
}
case 'testTimeout': {
if (oldOptions[key] < 0) {
throw createConfigError(
` Option "${chalk.bold('testTimeout')}" must be a natural number.`,
);
}

value = oldOptions[key];
break;
}
case 'automock':
case 'browser':
case 'cache':
Expand Down
Expand Up @@ -112,6 +112,7 @@ exports[`prints the config object 1`] = `
"testNamePattern": "",
"testPathPattern": "",
"testResultsProcessor": null,
"testTimeout": 5000,
"updateSnapshot": "none",
"useStderr": false,
"verbose": false,
Expand Down
1 change: 1 addition & 0 deletions packages/jest-jasmine2/src/index.ts
Expand Up @@ -34,6 +34,7 @@ async function jasmine2(
const jasmine = jasmineFactory.create({
process,
testPath,
testTimeout: globalConfig.testTimeout,
});

const env = jasmine.getEnv();
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-jasmine2/src/jasmine/jasmineLight.ts
Expand Up @@ -43,7 +43,7 @@ import Timer from './Timer';
const create = function(createOptions: Record<string, any>): Jasmine {
const j$ = {...createOptions} as Jasmine;

j$._DEFAULT_TIMEOUT_INTERVAL = 5000;
j$._DEFAULT_TIMEOUT_INTERVAL = createOptions.testTimeout || 5000;

j$.getEnv = function(options?: object) {
const env = (j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options));
Expand Down
3 changes: 3 additions & 0 deletions packages/jest-types/src/Config.ts
Expand Up @@ -207,6 +207,7 @@ export type InitialOptions = {
testRunner?: string;
testSequencer?: string;
testURL?: string;
testTimeout?: number;
timers?: 'real' | 'fake';
transform?: {
[key: string]: string;
Expand Down Expand Up @@ -344,6 +345,7 @@ export type GlobalConfig = {
testPathPattern: string;
testResultsProcessor: string | null | undefined;
testSequencer: string;
testTimeout: number;
updateSnapshot: SnapshotUpdateState;
useStderr: boolean;
verbose: boolean | null | undefined;
Expand Down Expand Up @@ -489,6 +491,7 @@ export type Argv = Arguments<
testRunner: string;
testSequencer: string;
testURL: string;
testTimeout: number | null | undefined;
timers: string;
transform: string;
transformIgnorePatterns: Array<string>;
Expand Down

0 comments on commit 46f9a97

Please sign in to comment.