# test isolation: a worked example

Canonical page: https://vibe-coding-101.brighteng.org/c/test-isolation/#before-and-after

## The problem

One test adds a cart item. Another expects a fresh empty cart. Both pass with a fresh process, but the empty-cart check fails after the first test mutates the shared fixture.

## Prompt to paste

Isolate these tests with independent sessions and records. Verify they pass alone and together in parallel.

## Before

A fixture factory always returns the same cart. One test leaves state for the next; changing their order changes the outcome.

## After

Create a new cart for each test rather than sharing the mutable object. Test independence in both orders. In an application, apply the same ownership rule to sessions, records, files, and other mutable resources.

## Run the check

Save the following code as test-isolation.mjs and run `node --test test-isolation.mjs` with Node.js 22.12 or later.

```js
import test from 'node:test';
import assert from 'node:assert/strict';

function before() {
  const shared = { items: [] };
  return () => shared;
}

function after() {
  return () => ({ items: [] });
}

function addItem(makeCart) {
  const cart = makeCart();
  cart.items.push('book');
  assert.equal(cart.items.length, 1);
}
function startsEmpty(makeCart) {
  assert.deepEqual(makeCart().items, []);
}

test('checks pass alone but interfere when sharing the fixture', () => {
  addItem(before());
  startsEmpty(before());
  const shared = before();
  addItem(shared);
  assert.throws(() => startsEmpty(shared), { code: 'ERR_ASSERTION' });
});

test('independent fixtures pass in both orders and overlapping owners', () => {
  for (const order of [[addItem, startsEmpty], [startsEmpty, addItem]]) {
    const fixture = after();
    for (const check of order) check(fixture);
  }
  const fixture = after();
  const first = fixture(), second = fixture();
  first.items.push('book');
  assert.deepEqual(second.items, []);
});
```

## Expected result

The shared-fixture example reproduces the exact alone-versus-together mismatch. Independent fixtures pass in both orders and retain separate mutable state when two owners exist at once.

## Limits

Fresh objects isolate this memory-only example. Separate objects do not isolate a shared database row, account, port, or filesystem path. Give parallel tests unique resources or a safe reset boundary, close resources, and restore mocks and clocks. These checks do not run multiple OS processes or measure suite flakiness; verify the actual suite under its real parallel settings.

## Sources

- [Playwright: Test isolation](https://playwright.dev/docs/best-practices#make-tests-as-isolated-as-possible): Independent tests should own their storage, session, cookies, and data. The cart example is an original memory-only illustration.

Sources checked: 2026-10-11. These are original illustrative examples with automated checks. Human editorial approval is not recorded. Policy: https://vibe-coding-101.brighteng.org/editorial/
