playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Feature]: Concurrent execution of the tests required

Open raghav135 opened this issue 2 months ago • 3 comments

🚀 Feature Request

When executing tests, one is unable to run the tests concurrently.

The concurrent execution is tightly coupled with workers, which need not be the case.

We need to execute 100s of backend tests (Not UI based) that sends a message, wait few seconds, then check the response in DB for example. We cannot have 100s of workers, and we also have to wait "sequentially" since the concurrency is currently tied with workers.

Example

The below code should execute in 3 seconds even if the number of workers is 1, but it is currently taking 9 seconds.

import { test } from '@playwright/test';

test.describe.configure({ mode: 'parallel' });

const delay = (ms: number) => new Promise(r => setTimeout(r, ms));

test('test A - 3s delay', async () => {
  const start = Date.now();
  console.log('A started at', new Date().toISOString());
  await delay(3000);
  console.log('A ended after', (Date.now() - start) / 1000, 'seconds');
});

test('test B - 3s delay', async () => {
  const start = Date.now();
  console.log('B started at', new Date().toISOString());
  await delay(3000);
  console.log('B ended after', (Date.now() - start) / 1000, 'seconds');
});

test('test C - 3s delay', async () => {
  const start = Date.now();
  console.log('C started at', new Date().toISOString());
  await delay(3000);
  console.log('C ended after', (Date.now() - start) / 1000, 'seconds');
});

Output:

Running 3 tests using 1 worker

A started at 2025-11-05T09:26:50.618Z
A ended after 3.002 seconds
  ✓  1 [api] › tests/parallel.spec.ts:7:5 › test A - 3s delay (3.0s)
B started at 2025-11-05T09:26:53.636Z
B ended after 3.001 seconds
  ✓  2 [api] › tests/parallel.spec.ts:14:5 › test B - 3s delay (3.0s)
C started at 2025-11-05T09:26:56.651Z
C ended after 3.002 seconds
  ✓  3 [api] › tests/parallel.spec.ts:21:5 › test C - 3s delay (3.0s)

  3 passed (9.7s)

Motivation

Enterprises are adopting "playwright" as the defacto standard for automation testing. But the backend testing needs such improvements for large organizations to adopt this better.

Frameworks like vitest already support this feature, example:

import { test, expect } from 'vitest';

const delay = (ms: number) => new Promise(r => setTimeout(r, ms));

test.concurrent('test A - 3s delay', async () => {
  const start = Date.now();
  console.log('A started at', new Date().toISOString());
  await delay(3000);
  console.log('A ended after', (Date.now() - start) / 1000, 'seconds');
  expect(true).toBe(true);
});

test.concurrent('test B - 3s delay', async () => {
  const start = Date.now();
  console.log('B started at', new Date().toISOString());
  await delay(3000);
  console.log('B ended after', (Date.now() - start) / 1000, 'seconds');
  expect(true).toBe(true);
});

test.concurrent('test C - 3s delay', async () => {
  const start = Date.now();
  console.log('C started at', new Date().toISOString());
  await delay(3000);
  console.log('C ended after', (Date.now() - start) / 1000, 'seconds');
  expect(true).toBe(true);
});

vitest.config.ts:

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    pool: 'threads',
    maxThreads: 1,
    minThreads: 1,
  },
});

Output from vitest

❯ npx vitest run

 RUN  v4.0.7 /Users/ramakrs7/work/vitest

stdout | parallel.test.ts > test C - 3s delay
A started at 2025-11-05T09:29:03.228Z
B started at 2025-11-05T09:29:03.228Z
C started at 2025-11-05T09:29:03.228Z

stdout | parallel.test.ts > test C - 3s delay
A ended after 3.002 seconds

stdout | parallel.test.ts
B ended after 3.006 seconds

stdout | parallel.test.ts
C ended after 3.007 seconds

 ✓ parallel.test.ts (3 tests) 3008ms
   ✓ test A - 3s delay  3006ms
   ✓ test B - 3s delay  3007ms
   ✓ test C - 3s delay  3007ms

 Test Files  1 passed (1)
      Tests  3 passed (3)
   Start at  14:59:03
   Duration  3.08s (transform 9ms, setup 0ms, collect 13ms, tests 3.01s, environment 0ms, prepare 2ms)

raghav135 avatar Nov 05 '25 09:11 raghav135

~In your scenario where you run 100 tests concurrently, do you have 100 browsers running as well?~

Ah, I see that you are using @playwright/test for the API testing.

We are not too comfortable running tests in a single Node concurrently:

  • a failure in one test can lead to the side-effects in the other tests
  • unhandled errors can't be contributed to the failing test too

That, in combination with the regular @playwright/test application where the browser is present, produced the current architecture.

pavelfeldman avatar Nov 05 '25 23:11 pavelfeldman

Sounds like you're trying to do API load testing, I would recommend k6 for this not Playwright

alisterscott avatar Dec 09 '25 00:12 alisterscott

Sounds like you're trying to do API load testing, I would recommend k6 for this not Playwright

Hi, thanks for your reply. It is just lots of tests , with each having to wait a bit for verifying results.

raghav135 avatar Dec 10 '25 03:12 raghav135