mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-14 05:37:20 +03:00
feat(test runner): workers as percentage (#17400)
Allows to set workers as a percentage of logical CPUs, for example "50%". Examples : ```bash npx playwright test --workers 3 npx playwright test --workers 50% ``` ```js const config: PlaywrightTestConfig = { // ... workers: '33%', } ```
This commit is contained in:
parent
d2300674ef
commit
a15fe50e7b
@ -791,13 +791,13 @@ module.exports = config;
|
||||
|
||||
## property: TestConfig.workers
|
||||
* since: v1.10
|
||||
- type: ?<[int]>
|
||||
- type: ?<[int]|[string]>
|
||||
|
||||
The maximum number of concurrent worker processes to use for parallelizing tests.
|
||||
The maximum number of concurrent worker processes to use for parallelizing tests. Can also be set as percentage of logical CPU cores, e.g. `'50%'.`
|
||||
|
||||
Playwright Test uses worker processes to run tests. There is always at least one worker process, but more can be used to speed up test execution.
|
||||
|
||||
Defaults to one half of the number of CPU cores. Learn more about [parallelism and sharding](../test-parallel.md) with Playwright Test.
|
||||
Defaults to half of the number of logical CPU cores. Learn more about [parallelism and sharding](../test-parallel.md) with Playwright Test.
|
||||
|
||||
```js tab=js-js
|
||||
// playwright.config.js
|
||||
|
@ -516,7 +516,7 @@ In addition to configuring [Browser] or [BrowserContext], videos or screenshots,
|
||||
- `testMatch`: Glob patterns or regular expressions that match test files. For example, `'**/todo-tests/*.spec.ts'`. By default, Playwright Test runs `.*(test|spec)\.(js|ts|mjs)` files.
|
||||
- `timeout`: Time in milliseconds given to each test. Learn more about [various timeouts](./test-timeouts.md).
|
||||
- `webServer: { command: string, port?: number, url?: string, ignoreHTTPSErrors?: boolean, timeout?: number, reuseExistingServer?: boolean, cwd?: string, env?: object }` - Launch a process and wait that it's ready before the tests will start. See [launch web server](./test-advanced.md#launching-a-development-web-server-during-the-tests) configuration for examples.
|
||||
- `workers`: The maximum number of concurrent worker processes to use for parallelizing tests.
|
||||
- `workers`: The maximum number of concurrent worker processes to use for parallelizing tests. Can also be set as percentage of logical CPU cores, e.g. `'50%'.`
|
||||
|
||||
You can specify these options in the configuration file. Note that testing options are **top-level**, do not put them into the `use` section.
|
||||
|
||||
|
@ -100,7 +100,7 @@ function addTestCommand(program: Command) {
|
||||
command.option('-gv, --grep-invert <grep>', `Only run tests that do not match this regular expression`);
|
||||
command.option('--global-timeout <timeout>', `Maximum time this test suite can run in milliseconds (default: unlimited)`);
|
||||
command.option('--ignore-snapshots', `Ignore screenshot and snapshot expectations`);
|
||||
command.option('-j, --workers <workers>', `Number of concurrent workers, use 1 to run in a single worker (default: number of CPU cores / 2)`);
|
||||
command.option('-j, --workers <workers>', `Number of concurrent workers or percentage of logical CPU cores, use 1 to run in a single worker (default: 50%)`);
|
||||
command.option('--list', `Collect all the tests and report them, but do not run`);
|
||||
command.option('--max-failures <N>', `Stop after the first N failures`);
|
||||
command.option('--output <dir>', `Folder for output artifacts (default: "test-results")`);
|
||||
@ -272,7 +272,7 @@ function overridesFromOptions(options: { [key: string]: any }): ConfigCLIOverrid
|
||||
timeout: options.timeout ? parseInt(options.timeout, 10) : undefined,
|
||||
ignoreSnapshots: options.ignoreSnapshots ? !!options.ignoreSnapshots : undefined,
|
||||
updateSnapshots: options.updateSnapshots ? 'all' as const : undefined,
|
||||
workers: options.workers ? parseInt(options.workers, 10) : undefined,
|
||||
workers: options.workers,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@ import type { Reporter } from '../types/testReporter';
|
||||
import { builtInReporters } from './runner';
|
||||
import { isRegExp, calculateSha1 } from 'playwright-core/lib/utils';
|
||||
import { serializeError } from './util';
|
||||
import { hostPlatform } from 'playwright-core/lib/utils/hostPlatform';
|
||||
import { FixturePool, isFixtureOption } from './fixtures';
|
||||
import type { TestTypeImpl } from './testType';
|
||||
|
||||
@ -143,7 +142,19 @@ export class Loader {
|
||||
this._fullConfig.shard = takeFirst(config.shard, baseFullConfig.shard);
|
||||
this._fullConfig._ignoreSnapshots = takeFirst(config.ignoreSnapshots, baseFullConfig._ignoreSnapshots);
|
||||
this._fullConfig.updateSnapshots = takeFirst(config.updateSnapshots, baseFullConfig.updateSnapshots);
|
||||
this._fullConfig.workers = takeFirst(config.workers, baseFullConfig.workers);
|
||||
|
||||
const workers = takeFirst(config.workers, '50%');
|
||||
if (typeof workers === 'string') {
|
||||
if (workers.endsWith('%')) {
|
||||
const cpus = os.cpus().length;
|
||||
this._fullConfig.workers = Math.max(1, Math.floor(cpus * (parseInt(workers, 10) / 100)));
|
||||
} else {
|
||||
this._fullConfig.workers = parseInt(workers, 10);
|
||||
}
|
||||
} else {
|
||||
this._fullConfig.workers = workers;
|
||||
}
|
||||
|
||||
const webServers = takeFirst(config.webServer, baseFullConfig.webServer);
|
||||
if (Array.isArray(webServers)) { // multiple web server mode
|
||||
// Due to previous choices, this value shows up to the user in globalSetup as part of FullConfig. Arrays are not supported by the old type.
|
||||
@ -572,8 +583,10 @@ function validateConfig(file: string, config: Config) {
|
||||
}
|
||||
|
||||
if ('workers' in config && config.workers !== undefined) {
|
||||
if (typeof config.workers !== 'number' || config.workers <= 0)
|
||||
if (typeof config.workers === 'number' && config.workers <= 0)
|
||||
throw errorWithFile(file, `config.workers must be a positive number`);
|
||||
else if (typeof config.workers === 'string' && !config.workers.endsWith('%'))
|
||||
throw errorWithFile(file, `config.workers must be a number or percentage`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -631,9 +644,6 @@ function validateProject(file: string, project: Project, title: string) {
|
||||
}
|
||||
}
|
||||
|
||||
const cpus = os.cpus().length;
|
||||
const workers = hostPlatform.startsWith('mac') && hostPlatform.endsWith('arm64') ? cpus : Math.ceil(cpus / 2);
|
||||
|
||||
export const baseFullConfig: FullConfigInternal = {
|
||||
forbidOnly: false,
|
||||
fullyParallel: false,
|
||||
@ -654,7 +664,7 @@ export const baseFullConfig: FullConfigInternal = {
|
||||
shard: null,
|
||||
updateSnapshots: 'missing',
|
||||
version: require('../package.json').version,
|
||||
workers,
|
||||
workers: 0,
|
||||
webServer: null,
|
||||
_watchMode: false,
|
||||
_webServers: [],
|
||||
|
16
packages/playwright-test/types/test.d.ts
vendored
16
packages/playwright-test/types/test.d.ts
vendored
@ -936,13 +936,14 @@ interface TestConfig {
|
||||
updateSnapshots?: "all"|"none"|"missing";
|
||||
|
||||
/**
|
||||
* The maximum number of concurrent worker processes to use for parallelizing tests.
|
||||
* The maximum number of concurrent worker processes to use for parallelizing tests. Can also be set as percentage of
|
||||
* logical CPU cores, e.g. `'50%'.`
|
||||
*
|
||||
* Playwright Test uses worker processes to run tests. There is always at least one worker process, but more can be used to
|
||||
* speed up test execution.
|
||||
*
|
||||
* Defaults to one half of the number of CPU cores. Learn more about [parallelism and sharding](https://playwright.dev/docs/test-parallel) with
|
||||
* Playwright Test.
|
||||
* Defaults to half of the number of logical CPU cores. Learn more about [parallelism and sharding](https://playwright.dev/docs/test-parallel)
|
||||
* with Playwright Test.
|
||||
*
|
||||
* ```js
|
||||
* // playwright.config.ts
|
||||
@ -955,7 +956,7 @@ interface TestConfig {
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
workers?: number;}
|
||||
workers?: number|string;}
|
||||
|
||||
/**
|
||||
* Playwright Test provides many options to configure how your tests are collected and executed, for example `timeout` or
|
||||
@ -1210,13 +1211,14 @@ export interface FullConfig<TestArgs = {}, WorkerArgs = {}> {
|
||||
*/
|
||||
updateSnapshots: 'all' | 'none' | 'missing';
|
||||
/**
|
||||
* The maximum number of concurrent worker processes to use for parallelizing tests.
|
||||
* The maximum number of concurrent worker processes to use for parallelizing tests. Can also be set as percentage of
|
||||
* logical CPU cores, e.g. `'50%'.`
|
||||
*
|
||||
* Playwright Test uses worker processes to run tests. There is always at least one worker process, but more can be used to
|
||||
* speed up test execution.
|
||||
*
|
||||
* Defaults to one half of the number of CPU cores. Learn more about [parallelism and sharding](https://playwright.dev/docs/test-parallel) with
|
||||
* Playwright Test.
|
||||
* Defaults to half of the number of logical CPU cores. Learn more about [parallelism and sharding](https://playwright.dev/docs/test-parallel)
|
||||
* with Playwright Test.
|
||||
*
|
||||
* ```js
|
||||
* // playwright.config.ts
|
||||
|
@ -393,6 +393,41 @@ test('should support ignoreSnapshots config option', async ({ runInlineTest }) =
|
||||
expect(result.passed).toBe(1);
|
||||
});
|
||||
|
||||
test('should validate workers option set to percent', async ({ runInlineTest }, testInfo) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = {
|
||||
workers: '50%'
|
||||
};
|
||||
`,
|
||||
'a.test.ts': `
|
||||
const { test } = pwt;
|
||||
test('pass', async () => {
|
||||
});
|
||||
`
|
||||
});
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.passed).toBe(1);
|
||||
});
|
||||
|
||||
test('should throw when workers option is invalid', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = {
|
||||
workers: ''
|
||||
};
|
||||
`,
|
||||
'a.test.ts': `
|
||||
const { test } = pwt;
|
||||
test('pass', async () => {
|
||||
});
|
||||
`
|
||||
});
|
||||
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.output).toContain('config.workers must be a number or percentage');
|
||||
});
|
||||
|
||||
test('should work with undefined values and base', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
|
Loading…
Reference in New Issue
Block a user