Skip to content

test and describe

test.describe groups related scenarios and provides hooks for shared setup and teardown. This lesson shows how to structure suites cleanly.

Grouping with test.describe

Wrap related tests in test.describe('Feature name', () => { ... }). Nested describes further organize sub-features. Hooks like test.beforeEach run around each test in that describe block.

Use test.describe.configure({ mode: 'serial' }) when tests must run in order and share state — use sparingly because it disables parallelism within that group.

test.describe('Shopping cart', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/shop');
  });

  test('adds item', async ({ page }) => { /* ... */ });
  test('removes item', async ({ page }) => { /* ... */ });
});

beforeEach runs before every test in the describe, keeping setup DRY.

Hooks and Configuration

test.beforeAll(async () => { /* once per describe */ });
test.afterEach(async ({ page }) => { /* cleanup */ });
test.describe.configure({ mode: 'serial' });
test.describe.configure({ retries: 1 });
  • beforeAll / afterAll run once per describe block.
  • beforeEach / afterEach run around each test.
  • Describe-level configure overrides retries or parallel mode.
  • Nested describes inherit hooks from parent describes.

describe and Hooks Reference

When each hook runs.

Hook Runs
test.beforeAll Once before all tests in describe
test.afterAll Once after all tests in describe
test.beforeEach Before each test in describe
test.afterEach After each test in describe
describe.configure({ mode: 'serial' }) Tests run in order, not parallel
test.step() Report substeps inside a test

test.step for Readable Reports

test('checkout flow', async ({ page }) => {
  await test.step('Add to cart', async () => {
    await page.getByRole('button', { name: 'Add' }).click();
  });
  await test.step('Open checkout', async () => {
    await page.getByRole('link', { name: 'Checkout' }).click();
  });
});

Steps appear in HTML reports and traces, making failures easier to pinpoint.

Hooks Inside describe Blocks

test.beforeEach runs before every test in the block; test.afterEach cleans up. Use test.describe.configure({ mode: 'serial' }) when tests in one file must run in order.

Common Mistakes

  • Using serial mode everywhere, destroying parallel performance.
  • Putting heavy setup in beforeEach when beforeAll with careful isolation would suffice.
  • Sharing mutable state between parallel tests in the same describe.
  • Deep nesting of describes that obscures which hooks apply.

Key Takeaways

  • test.describe organizes tests and scopes hooks.
  • Prefer beforeEach for navigation and clean state per test.
  • Use serial mode only when order-dependent behavior is unavoidable.
  • test.step improves report readability for long flows.

Pro Tip

Keep describe titles user-facing ('Checkout') not implementation-facing ('tests for CartReducer') — CI output becomes documentation.