Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: add more informaton to Architecture page #7984

Merged
merged 6 commits into from Mar 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -79,6 +79,7 @@
- `[jest-validate]`: Migrate to TypeScript ([#7991](https://github.com/facebook/jest/pull/7991))
- `[docs]`: Update CONTRIBUTING.md to add information about running jest with `jest-circus` locally ([#8013](https://github.com/facebook/jest/pull/8013)).
- `[@jest/core]`: Migrate to TypeScript ([#7998](https://github.com/facebook/jest/pull/7998))
- `[docs]` Update/Organize TestSequencer and testSchedulerHelper code comments([#7984](https://github.com/facebook/jest/pull/7984))
- `[@jest/source-map]`: Extract `getCallsite` function from `jest-util` into a new separate package ([#8029](https://github.com/facebook/jest/pull/8029))
- `[@jest/console]`: Extract custom `console` implementations from `jest-util` into a new separate package ([#8030](https://github.com/facebook/jest/pull/8030))

Expand Down Expand Up @@ -512,7 +513,7 @@
- `[jest-jasmine2]` Add stack trace for thrown non-`Error`s ([#6008](https://github.com/facebook/jest/pull/6008))
- `[jest-runtime]` Prevent modules from marking themselves as their own parent ([#5235](https://github.com/facebook/jest/issues/5235))
- `[jest-mock]` Add support for auto-mocking generator functions ([#5983](https://github.com/facebook/jest/pull/5983))
- `[expect]` Add support for async matchers ([#5919](https://github.com/facebook/jest/pull/5919))
- `[expect]` Add support for async matchers ([#5919](https://github.com/facebook/jest/pull/5919))
- `[expect]` Suggest toContainEqual ([#5948](https://github.com/facebook/jest/pull/5953))
- `[jest-config]` Export Jest's default options ([#5948](https://github.com/facebook/jest/pull/5948))
- `[jest-editor-support]` Move `coverage` to `ProjectWorkspace.collectCoverage` ([#5929](https://github.com/facebook/jest/pull/5929))
Expand Down
39 changes: 31 additions & 8 deletions packages/jest-core/src/TestSequencer.ts
Expand Up @@ -18,6 +18,19 @@ type Cache = {
[key: string]: [0 | 1, number];
};

/**
* The TestSequencer will ultimately decide which tests should run first.
* It is responsible for storing and reading from a local cache
* map that stores context information for a given test, such as how long it
* took to run during the last run and if it has failed or not.
* Such information is used on:
* TestSequencer.sort(tests: Array<Test>)
* to sort the order of the provided tests.
*
* After the results are collected,
* TestSequencer.cacheResults(tests: Array<Test>, results: AggregatedResult)
* is called to store/update this information on the cache map.
*/
export default class TestSequencer {
private _cache: Map<Context, Cache>;

Expand Down Expand Up @@ -53,14 +66,24 @@ export default class TestSequencer {
return cache;
}

// When running more tests than we have workers available, sort the tests
// by size - big test files usually take longer to complete, so we run
// them first in an effort to minimize worker idle time at the end of a
// long test run.
//
// After a test run we store the time it took to run a test and on
// subsequent runs we use that to run the slowest tests first, yielding the
// fastest results.
/**
* Sorting tests is very important because it has a great impact on the
* user-perceived responsiveness and speed of the test run.
*
* If such information is on cache, tests are sorted based on:
* -> Has it failed during the last run ?
* Since it's important to provide the most expected feedback as quickly
* as possible.
* -> How long it took to run ?
* Because running long tests first is an effort to minimize worker idle
* time at the end of a long test run.
* And if that information is not available they are sorted based on file size
* since big test files usually take longer to complete.
*
* Note that a possible improvement would be to analyse other information
* from the file other than its size.
*
*/
sort(tests: Array<Test>): Array<Test> {
const stats: {[path: string]: number} = {};
const fileSize = ({path, context: {hasteFS}}: Test) =>
Expand Down
20 changes: 11 additions & 9 deletions packages/jest-core/src/testSchedulerHelper.ts
Expand Up @@ -15,16 +15,18 @@ export function shouldRunInBand(
maxWorkers: number,
timings: Array<number>,
) {
// Run in band if we only have one test or one worker available, unless we
// are using the watch mode, in which case the TTY has to be responsive and
// we cannot schedule anything in the main thread. Same logic applies to
// watchAll.
//
// If we are confident from previous runs that the tests will finish
// quickly we also run in band to reduce the overhead of spawning workers.
/**
* Run in band if we only have one test or one worker available, unless we
* are using the watch mode, in which case the TTY has to be responsive and
* we cannot schedule anything in the main thread. Same logic applies to
* watchAll.
* Also, if we are confident from previous runs that the tests will finish
* quickly we also run in band to reduce the overhead of spawning workers.
* Finally, the user can provide the runInBand argument in the CLI to
* force running in band.
* https://github.com/facebook/jest/blob/700e0dadb85f5dc8ff5dac6c7e98956690049734/packages/jest-config/src/getMaxWorkers.js#L14-L17
*/
const areFastTests = timings.every(timing => timing < SLOW_TEST_TIME);
// This apply also when runInBand arg present
// https://github.com/facebook/jest/blob/700e0dadb85f5dc8ff5dac6c7e98956690049734/packages/jest-config/src/getMaxWorkers.js#L14-L17
const oneWorkerOrLess = maxWorkers <= 1;
const oneTestOrLess = tests.length <= 1;

Expand Down