Skip to content

Commit

Permalink
Moving ordering/band info from docs to comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Luanf committed Mar 1, 2019
1 parent 014bc68 commit eefa540
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 102 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -74,6 +74,7 @@
- `[jest-repl]`: Migrate to TypeScript ([#8000](https://github.com/facebook/jest/pull/8000))
- `[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)).
- `[docs]` Update/Organize TestSequencer and testSchedulerHelper code comments([#7984](https://github.com/facebook/jest/pull/7984))

### Performance

Expand Down Expand Up @@ -505,7 +506,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
25 changes: 0 additions & 25 deletions docs/Architecture.md
Expand Up @@ -6,28 +6,3 @@ title: Architecture
If you are interested in learning more about how Jest works, what the architecture behind the framework is, and how Jest is split up into individual reusable packages, check out this video:

<iframe width="560" height="315" src="https://www.youtube.com/embed/3YDiloj8_d0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# Tests ordering and parallelization

Jest can make decisions regarding tests ordering and how it is going to apply parallelization to such tests.

After gathering all tests it is supposed to run (based on, for instance, the command executed), it gathers important information to decide on the executing order.

Currently, some heuristics are:

- Has it failed during the last run?

- How long did this test took to run?

- What is the test file size?

Tests that have previously failed and tests that take the longest time get scheduled to run first.

If that information is not yet available, Jest gives priority to larger test files.

> **Note: The order in which tests are executed can change between different test runs.**
Regarding parallelization, Jest has the following rules:

- If `--runInBand` is not provided, Jest will decide if individual files will be executed in parallel or not based on a performance evaluation. If provided, all tests will be executed in a serial fashion using just one process.
- All `describe` and `test` blocks **within a file** always run in serial, in declaration order.
39 changes: 31 additions & 8 deletions packages/jest-core/src/TestSequencer.js
Expand Up @@ -21,6 +21,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 {
_cache: Map<Context, Cache>;

Expand Down Expand Up @@ -56,14 +69,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 = {};
const fileSize = ({path, context: {hasteFS}}) =>
Expand Down
20 changes: 11 additions & 9 deletions packages/jest-core/src/testSchedulerHelper.js
Expand Up @@ -17,16 +17,18 @@ export function shouldRunInBand(
maxWorkers: number,
timings: 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
25 changes: 0 additions & 25 deletions website/versioned_docs/version-24.0/Architecture.md
Expand Up @@ -7,28 +7,3 @@ original_id: architecture
If you are interested in learning more about how Jest works, what the architecture behind the framework is, and how Jest is split up into individual reusable packages, check out this video:

<iframe width="560" height="315" src="https://www.youtube.com/embed/3YDiloj8_d0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# Tests ordering and parallelization

Jest can make decisions regarding tests ordering and how it is going to apply parallelization to such tests.

After gathering all tests it is supposed to run (based on, for instance, the command executed), it gathers important information to decide on the executing order.

Currently, some heuristics are:

- Has it failed during the last run?

- How long did this test took to run?

- What is the test file size?

Tests that have previously failed and tests that take the longest time get scheduled to run first.

If that information is not yet available, Jest gives priority to larger test files.

> **Note: The order in which tests are executed can change between different test runs.**
Regarding parallelization, Jest has the following rules:

- If `--runInBand` is not provided, Jest will decide if individual files will be executed in parallel or not based on a performance evaluation. If provided, all tests will be executed in a serial fashion using just one process.
- All `describe` and `test` blocks **within a file** always run in serial, in declaration order.
34 changes: 0 additions & 34 deletions website/versioned_docs/version-24.1/Architecture.md

This file was deleted.

0 comments on commit eefa540

Please sign in to comment.