# Organising Tests and Test Data Factories — Jest, Vitest & Testing Library

Source: https://www.skillbyai.com/en/javascript-testing/q-organise

> Where tests live and how to build data.

## Colocate tests, centralise helpers

Most frontend projects **colocate** tests next to the code (`Button.tsx` and `Button.test.tsx`) so they move together, and keep shared helpers in one place such as `src/test/` (setup file, MSW handlers, custom render, factories). Name files consistently so the runner's include pattern finds them. For data, use **factories**: small functions that return a valid object with sensible defaults and accept overrides, so each test states only the fields it cares about. Factories avoid giant shared fixture files that every test silently depends on, and keep types honest because they return the real TypeScript type. Libraries such as `@faker-js/faker` or `fishery` can help, but a typed function is often enough; avoid random data unless you seed it.

## A suite the whole team trusts

A healthy suite is organised, fast, deterministic and runs on every change in CI.

![Three ideas: organisation and factories, flaky tests and debugging, CI; plus a checklist.](assets/figures/javascript-testing/section-8-map.svg) — Figure 8.1 — Organise tests, debug flakiness, run everything in CI.

## A typed factory with overrides

Each test states only what matters.

```typescript
// src/test/factories.ts
import type { Order, User } from '../types';

let seq = 0;
const nextId = (prefix: string) => `${prefix}_${++seq}`;

export function buildUser(overrides: Partial<User> = {}): User {
  return { id: nextId('u'), name: 'Test User', email: 'user@example.com', role: 'member', ...overrides };
}

export function buildOrder(overrides: Partial<Order> = {}): Order {
  return { id: nextId('o'), userId: buildUser().id, items: [], status: 'pending', totalCents: 0, ...overrides };
}

// in a test: only the relevant field is visible
// const admin = buildUser({ role: 'admin' });
// const shipped = buildOrder({ status: 'shipped', totalCents: 4200 });

// project layout
// src/components/Button.tsx
// src/components/Button.test.tsx
// src/test/{setup.ts, server.ts, handlers.ts, test-utils.tsx, factories.ts}
```

## Make the important value obvious

If a test is about admins, write `buildUser({ role: 'admin' })` in the test even if `admin` were the default. Readers should not need to open the factory to understand why a test passes.

**Quiz:** What is the main benefit of a test data factory with overrides?

- [ ] It replaces MSW handlers
- [ ] It removes the need for assertions
- [ ] It makes data random on every run
- [x] Tests specify only the fields they care about while still getting valid objects

*Answer:* Tests specify only the fields they care about while still getting valid objects. Defaults plus overrides keep tests short and explicit.
