diff --git a/CHANGELOG.md b/CHANGELOG.md index 69eea7572b77..ffa3830e0bfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ - `[expect]` `expect(Infinity).toBeCloseTo(Infinity)` Treats `Infinity` as equal in toBeCloseTo matcher ([#7405](https://github.com/facebook/jest/pull/7405)) - `[jest-worker]` Add node worker-thread support to jest-worker ([#7408](https://github.com/facebook/jest/pull/7408)) - `[jest-config]` Allow `bail` setting to be configured with a number allowing tests to abort after `n` of failures ([#7335](https://github.com/facebook/jest/pull/7335)) +- `[jest-config]` Allow % based configuration of `--max-workers` ([#7494](https://github.com/facebook/jest/pull/7494)) ### Fixes diff --git a/docs/CLI.md b/docs/CLI.md index f19cf7579a1a..7ca495392a35 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -193,10 +193,12 @@ Lists all tests as JSON that Jest will run given the arguments, and exits. This Logs the heap usage after every test. Useful to debug memory leaks. Use together with `--runInBand` and `--expose-gc` in node. -### `--maxWorkers=` +### `--maxWorkers=|` Alias: `-w`. Specifies the maximum number of workers the worker-pool will spawn for running tests. This defaults to the number of the cores available on your machine. It may be useful to adjust this in resource limited environments like CIs but the default should be adequate for most use-cases. +For environments with variable CPUs available, you can use percentage based configuration: `--maxWorkers=50%` + ### `--noStackTrace` Disables stack trace in test results output. diff --git a/packages/jest-config/src/__tests__/getMaxWorkers.test.js b/packages/jest-config/src/__tests__/getMaxWorkers.test.js index 5b0d9fb26b95..0545ef8e6cc4 100644 --- a/packages/jest-config/src/__tests__/getMaxWorkers.test.js +++ b/packages/jest-config/src/__tests__/getMaxWorkers.test.js @@ -34,4 +34,21 @@ describe('getMaxWorkers', () => { expect(getMaxWorkers({})).toBe(3); expect(getMaxWorkers({watch: true})).toBe(2); }); + + describe('% based', () => { + it('50% = 2 workers', () => { + const argv = {maxWorkers: '50%'}; + expect(getMaxWorkers(argv)).toBe(2); + }); + + it('< 0 workers should become 1', () => { + const argv = {maxWorkers: '1%'}; + expect(getMaxWorkers(argv)).toBe(1); + }); + + it("0% shouldn't break", () => { + const argv = {maxWorkers: '0%'}; + expect(getMaxWorkers(argv)).toBe(1); + }); + }); }); diff --git a/packages/jest-config/src/getMaxWorkers.js b/packages/jest-config/src/getMaxWorkers.js index 307ef02c9653..80deadc427d0 100644 --- a/packages/jest-config/src/getMaxWorkers.js +++ b/packages/jest-config/src/getMaxWorkers.js @@ -15,7 +15,20 @@ export default function getMaxWorkers(argv: Argv): number { if (argv.runInBand) { return 1; } else if (argv.maxWorkers) { - return parseInt(argv.maxWorkers, 10); + const parsed = parseInt(argv.maxWorkers, 10); + + if ( + typeof argv.maxWorkers === 'string' && + argv.maxWorkers.trim().endsWith('%') && + parsed > 0 && + parsed <= 100 + ) { + const cpus = os.cpus().length; + const workers = Math.floor((parsed / 100) * cpus); + return workers >= 1 ? workers : 1; + } + + return parsed > 0 ? parsed : 1; } else { const cpus = os.cpus() ? os.cpus().length : 1; return Math.max(argv.watch ? Math.floor(cpus / 2) : cpus - 1, 1);