In Playwright, when a test.describe.serial group hits a failure, what happens to the rest?
answer
- One dependent unit, one worker
- Later tests are skipped
- Retry does not resume mid-chain
- Whole group replays from the top
- Skips are not passes
basics
~20 sThe tests after the failure are skipped rather than run. A retry does not resume at the failure: the whole group reruns from its first test, because serial mode treats the block as one ordered unit.
solid answer
~40 sA group marked with `test.describe.serial(...)`, or with `test.describe.configure({ mode: 'serial' })`, runs its tests in declaration order in a single worker and treats them as one dependent unit. As soon as one test fails, every test declared after it in that group is marked skipped instead of being executed, because the runner assumes they depended on the failed step. If retries are enabled, the retry does not resume at the failing test; the entire group is rerun from the beginning, so the earlier passing tests execute again. That is the practical difference from the ordinary default schedule, where tests in a file are also ordered but independent, so a failure neither skips the rest nor drags them into a retry.
code
typescript · 16 linesimport { test, expect } from '@playwright/test';
test.describe.serial('monthly payroll close', () => {
test('opens the pay period', async ({ page }) => {
await page.goto('/payroll/periods');
await page.getByRole('button', { name: 'Open period' }).click();
await expect(page.getByText('Period open')).toBeVisible();
});
test('approves the run', async ({ page }) => {
// Skipped when the test above fails; both rerun together on a retry.
await page.goto('/payroll/periods/current');
await page.getByRole('button', { name: 'Approve' }).click();
await expect(page.getByText('Approved')).toBeVisible();
});
});go deeper
Learn the two facts: a failure skips the rest of the serial group, and a retry starts the group over from its first test.
Explain why, using the dependency assumption serial encodes, and contrast it with the default file schedule where a failure skips nothing.
Bring the operational angle: skipped tails hide coverage in dashboards, and long serial chains multiply their whole duration by the retry count.
Frame the tradeoff of encoding dependency in the runner at all, and where the boundary sits between a short justified chain and a suite that only ever passes in order.
## What serial mode declares Marking a block serial, either as `test.describe.serial('title', fn)` or by calling `test.describe.configure({ mode: 'serial' })` inside a `test.describe`, tells the runner three things at once: - The tests in the block run **in declaration order**. - They run **in one worker process**, never spread across several. - They are **one dependent unit**: later tests are assumed to need the earlier ones to have passed. The third point is the one candidates miss, and it is where all the surprising behaviour comes from. ## What a failure does When a test in a serial group fails: 1. The remaining tests in that group are **skipped**, not run and not failed. They appear in the report as skipped, so the report shows one failure plus a tail of skips rather than a cascade of failures. 2. Sibling files and other groups are unaffected — they keep running in parallel as usual. 3. If a `beforeAll` hook of the group fails, the same thing happens to every test in the group. ## What a retry does This is the half interviewers actually probe. Retries do not resume in the middle of a dependent chain, because the state the failing test needed was built by its predecessors in the same worker. So the runner **reruns the whole group from its first test**. Consequences worth stating out loud: - Tests that already passed run a second time, and their duration is paid again. - A three-minute group with a flaky last step costs three minutes per attempt, not the few seconds the flaky step takes. - The report shows the earlier tests with an extra attempt attached even though they never failed. ## Serial versus the ordinary default schedule | | default file schedule | `mode: 'serial'` group | |---|---|---| | Order | declaration order | declaration order | | Worker | one worker for the file | one worker for the group | | After a failure | later tests still run | later tests are skipped | | On retry | only the failed test rerun | the whole group rerun | | Can be split across workers | no | no | The rows that differ are the last three, and "ordered" alone is not what serial buys you — a file is already ordered by default. Serial buys you **skip-on-failure and group-level retry**. ## A payroll example In a payroll regression suite, a close-the-period chain looks like open period, run calculation, approve, export to the bank. Marked serial, a failure in *approve* leaves *export* skipped, which is the honest report: the export was never exercised, so calling it passed or failed would both be wrong. On retry, *open* and *run calculation* execute again to rebuild the state that *approve* needs. ## Pitfalls and how to talk about them - **Do not read skipped as passed.** A green-ish looking run with many skips inside serial groups is hiding untested surface, and dashboards that count only failures will under-report it. - **Watch the retry bill.** Long serial groups multiply their whole duration by the attempt count; keeping the serial span down to the two or three genuinely dependent tests keeps that bill small. - **Serial is not a lock.** It orders tests inside the group only; other files still run beside it, so it does not protect a shared payroll record from a test in another file. - **The shorthand and the configure call are the same thing.** `test.describe.serial` is sugar for a describe with `mode: 'serial'`, so do not present them as two mechanisms. ## How to answer Say the two behaviours in one sentence — "later tests are skipped, and a retry reruns the group from the top" — then justify them with the dependency assumption serial mode encodes, then name the cost, which is wall-clock paid per attempt for the whole chain.
- Why does the runner skip the later tests instead of just failing them?Because serial mode declares them dependent on the earlier steps. A test that never ran against valid state has produced no evidence, so reporting it as failed would invent a defect and reporting it as passed would hide one. Skipped is the only honest verdict.
- How does a serial group interact with the rest of the suite while it runs?Only the group is constrained. Its tests occupy one worker in order, while other files and other groups continue to run in parallel on the remaining workers. Serial narrows the schedule inside the block, not across the run.
- What is the wall-clock cost of a retry on a long serial group?The full group duration, paid again per attempt, because the rerun starts at the first test rather than the failing one. A ten-minute chain with two retries can cost thirty minutes, which is why the serial span should cover only the genuinely dependent tests.
saying these in an interview costs you the question
- Says the remaining tests fail rather than skip
- Thinks a retry resumes at the failing test
- Treats skipped tests in the report as passes
- Believes serial mode blocks other files from running
- Claims serial is just ordering, which files already have