From eefa5403a1dd67cc0196fead7567687cee390da0 Mon Sep 17 00:00:00 2001 From: Luan Ferreira Date: Fri, 1 Mar 2019 19:20:12 -0300 Subject: [PATCH] Moving ordering/band info from docs to comments --- CHANGELOG.md | 3 +- docs/Architecture.md | 25 ------------ packages/jest-core/src/TestSequencer.js | 39 +++++++++++++++---- packages/jest-core/src/testSchedulerHelper.js | 20 +++++----- .../version-24.0/Architecture.md | 25 ------------ .../version-24.1/Architecture.md | 34 ---------------- 6 files changed, 44 insertions(+), 102 deletions(-) delete mode 100644 website/versioned_docs/version-24.1/Architecture.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 039968ce1d74..14c9c4564c7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 @@ -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)) diff --git a/docs/Architecture.md b/docs/Architecture.md index 63670a98448f..f069ea953eb7 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -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: - -# 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. diff --git a/packages/jest-core/src/TestSequencer.js b/packages/jest-core/src/TestSequencer.js index 0fab2560639c..6adf577ee5ed 100644 --- a/packages/jest-core/src/TestSequencer.js +++ b/packages/jest-core/src/TestSequencer.js @@ -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) + * to sort the order of the provided tests. + * + * After the results are collected, + * TestSequencer.cacheResults(tests: Array, results: AggregatedResult) + * is called to store/update this information on the cache map. + */ export default class TestSequencer { _cache: Map; @@ -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): Array { const stats = {}; const fileSize = ({path, context: {hasteFS}}) => diff --git a/packages/jest-core/src/testSchedulerHelper.js b/packages/jest-core/src/testSchedulerHelper.js index 37e22810f945..8c657885fd2d 100644 --- a/packages/jest-core/src/testSchedulerHelper.js +++ b/packages/jest-core/src/testSchedulerHelper.js @@ -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; diff --git a/website/versioned_docs/version-24.0/Architecture.md b/website/versioned_docs/version-24.0/Architecture.md index 036f563cfe54..42ee5d5c06fe 100644 --- a/website/versioned_docs/version-24.0/Architecture.md +++ b/website/versioned_docs/version-24.0/Architecture.md @@ -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: - -# 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. diff --git a/website/versioned_docs/version-24.1/Architecture.md b/website/versioned_docs/version-24.1/Architecture.md deleted file mode 100644 index 1e9e9112d3a5..000000000000 --- a/website/versioned_docs/version-24.1/Architecture.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -id: version-24.1-architecture -title: Architecture -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: - - - -# 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.