# Jest User Guide

Jest is a JavaScript and TypeScript testing framework with a focus on simplicity. It works out of the box for most projects, runs your tests in parallel across isolated worker processes, and ships with everything you need to write tests: a test runner, an assertion library (`expect`), built-in mocking, snapshot testing, and code-coverage reporting — with zero configuration required to get started.

This guide is for people who **write tests with Jest**. It covers installing Jest, writing your first test, the global test functions, the full matcher reference, mocking, snapshot testing, asynchronous tests, the command-line options, and everyday configuration. For Jest's internal architecture, the complete configuration reference, and how to build custom runners, environments, and reporters, see the Admin Guide.

> [!NOTE]
> Every command, flag, configuration key, and default value in this guide is taken directly from Jest's source code. Where a default is shown, it is the value Jest actually ships.

---

## 1. Quick Start

Get a passing test running in under two minutes.

**1. Install Jest as a development dependency:**

```bash
npm install --save-dev jest
```

**2. Create a function to test** — `sum.js`:

```javascript
function sum(a, b) {
  return a + b;
}
module.exports = sum;
```

**3. Create a test file** — `sum.test.js`:

```javascript
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});
```

**4. Add a `test` script to `package.json`:**

```json
{
  "scripts": {
    "test": "jest"
  }
}
```

**5. Run your tests:**

```bash
npm test
```

```text
 PASS  ./sum.test.js
  ✓ adds 1 + 2 to equal 3 (5 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.5 s
Ran all test suites.
```

That is a complete, working test suite. No configuration file is needed — Jest discovered `sum.test.js` automatically because it matches the default test pattern.

> [!TIP]
> You do not need to create a `jest.config.js` to start. Jest's defaults are designed to work for the majority of projects. Add configuration only when you need to change a default.

---

## 2. Installation & Requirements

### 2.1 Requirements

| Requirement | Detail |
|---|---|
| Node.js | `^18.14.0 \|\| ^20.0.0 \|\| ^22.0.0 \|\| >=24.0.0` (Node 18.14+, 20, 22, or 24+) |
| Package manager | npm, yarn, or pnpm |
| OS | Linux, macOS, Windows |

> [!IMPORTANT]
> Jest will not install on Node versions outside the supported range above. Odd-numbered Node releases (19, 21, 23) are not in the supported set — use an active LTS line (18.14+, 20, 22) or Node 24+.

### 2.2 Installing

=== "npm"

    ```bash
    npm install --save-dev jest
    ```

=== "yarn"

    ```bash
    yarn add --dev jest
    ```

=== "pnpm"

    ```bash
    pnpm add --save-dev jest
    ```

This installs the `jest` package, which bundles the command-line runner (`jest-cli`), the assertion library (`expect`), the default test runner (`jest-circus`), and the configuration loader (`jest-config`).

### 2.3 Running the `jest` binary

After installation, the `jest` command is available through your package manager:

```bash
npx jest
```

```text
 PASS  src/__tests__/example.test.js
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
```

You can also run a specific file or filter by a path substring:

```bash
npx jest path/to/my-test.js
npx jest wallet     # runs every test whose path contains "wallet"
```

### 2.4 Generating a configuration file (optional)

Jest ships a companion package, `create-jest`, that scaffolds a configuration file by asking you a few questions:

```bash
npm init jest@latest
```

```text
The following questions will help Jest to create a suitable configuration for your project

✔ Would you like to use Jest when running "test" script in "package.json"? … yes
✔ Would you like to use Typescript for the configuration file? … no
✔ Choose the test environment that will be used for testing › node
✔ Do you want Jest to add coverage reports? … no
✔ Which provider should be used to instrument code for coverage? › babel
✔ Automatically clear mock calls, instances, contexts and results before every test? … no

📝  Configuration file created at /your/project/jest.config.js
```

> [!NOTE]
> The old `jest --init` flag has been removed. Use the `create-jest` package (`npm init jest@latest`) instead.

---

## 3. Writing Tests

### 3.1 Test files

Jest automatically finds and runs files that match its default patterns. By default a file is treated as a test if it is:

- inside a `__tests__` directory, **or**
- named with a `.test.` or `.spec.` suffix

The exact default `testMatch` globs are:

```text
**/__tests__/**/*.?([mc])[jt]s?(x)
**/?(*.)+(spec|test).?([mc])[jt]s?(x)
```

This means all of the following are discovered automatically: `Button.test.js`, `Button.spec.ts`, `__tests__/button.tsx`, `api.test.mjs`, `utils.spec.cts`.

### 3.2 The `test` / `it` function

A test is declared with `test()` (or its alias `it()`), which takes a name and a function containing your assertions:

```javascript
test('a number is itself', () => {
  expect(1).toBe(1);
});

// `it` is an alias — identical behavior, reads naturally in BDD style
it('returns the user name', () => {
  expect(getUser().name).toBe('Ada');
});
```

A test passes if it runs to completion without any assertion throwing.

### 3.3 Grouping with `describe`

Use `describe()` to group related tests into a block. Blocks can be nested and are reflected in the output hierarchy:

```javascript
describe('calculator', () => {
  describe('add', () => {
    test('adds positive numbers', () => {
      expect(add(2, 3)).toBe(5);
    });

    test('adds negative numbers', () => {
      expect(add(-2, -3)).toBe(-5);
    });
  });
});
```

### 3.4 Setup and teardown hooks

Jest provides four hooks to run shared setup and cleanup code:

| Hook | Runs |
|---|---|
| `beforeAll(fn)` | Once, before all tests in the current block |
| `afterAll(fn)` | Once, after all tests in the current block |
| `beforeEach(fn)` | Before **every** test in the current block |
| `afterEach(fn)` | After **every** test in the current block |

```javascript
let db;

beforeAll(async () => {
  db = await connectToDatabase();
});

afterAll(async () => {
  await db.close();
});

beforeEach(async () => {
  await db.seed();
});

afterEach(async () => {
  await db.clear();
});

test('reads a record', async () => {
  expect(await db.get(1)).toEqual({id: 1, name: 'Ada'});
});
```

Hooks defined at the top level of a file apply to every test in that file. Hooks inside a `describe` apply only to tests within that block. Hooks return a Promise (or accept a `done` callback) to handle asynchronous setup — see [Section 7](#7-testing-asynchronous-code).

> [!TIP]
> `beforeEach`/`afterEach` execute in declaration order before each test; outer-block hooks run before inner-block hooks. Use `afterEach` for cleanup that must happen even if a test fails — Jest still runs it.

### 3.5 Focusing and skipping tests

During development you often want to run a single test or temporarily disable one. Use the `.only` and `.skip` modifiers on both `test` and `describe`:

```javascript
test.only('only this test runs in the file', () => {
  expect(true).toBe(true);
});

test.skip('temporarily disabled', () => {
  expect(brokenThing()).toBe(42);
});

test.todo('write a test for the edge case');  // shows as TODO in output

describe.only('only this block runs', () => { /* ... */ });
describe.skip('skipped block', () => { /* ... */ });
```

| Modifier | Effect |
|---|---|
| `test.only` / `it.only` | Run only this test (and other `.only` tests) in the file |
| `test.skip` / `it.skip` | Skip this test; report it as skipped |
| `test.todo` | Mark a test as planned but not yet written |
| `describe.only` | Run only tests inside this block |
| `describe.skip` | Skip every test inside this block |

### 3.6 Parameterized tests with `test.each`

Run the same test logic against a table of inputs using `test.each` (and `describe.each`):

```javascript
test.each([
  [1, 1, 2],
  [2, 3, 5],
  [10, -5, 5],
])('add(%i, %i) returns %i', (a, b, expected) => {
  expect(add(a, b)).toBe(expected);
});
```

You can also use a tagged-template form with named columns:

```javascript
test.each`
  a    | b    | expected
  ${1} | ${1} | ${2}
  ${2} | ${3} | ${5}
`('add($a, $b) returns $expected', ({a, b, expected}) => {
  expect(add(a, b)).toBe(expected);
});
```

Printf-style placeholders available in the test name include `%s` (string), `%i`/`%d` (number), `%j`/`%o`/`%p` (object), and `%#` (index of the row).

### 3.7 Concurrent tests

Run independent tests within a file in parallel with `test.concurrent`:

```javascript
test.concurrent('fetch A', async () => {
  expect(await fetchA()).toBeDefined();
});

test.concurrent('fetch B', async () => {
  expect(await fetchB()).toBeDefined();
});
```

The maximum number of concurrent tests per file is controlled by `maxConcurrency` (default `5`).

> [!WARNING]
> `test.concurrent` runs the test callbacks simultaneously. Do not use it for tests that share mutable state or rely on a specific execution order.

---

## 4. The `expect` API: Matchers

You make assertions by passing a value to `expect()` and chaining a **matcher**. Every matcher can be negated with `.not`:

```javascript
expect(value).toBe(4);
expect(value).not.toBe(5);
```

### 4.1 Equality and truthiness

| Matcher | Asserts that the value… |
|---|---|
| `toBe(expected)` | Is the same value (`Object.is`, reference/primitive identity). Do not use with floats. |
| `toEqual(expected)` | Recursively equals `expected` by value (ignores `undefined` properties). |
| `toStrictEqual(expected)` | Recursively equals `expected`, also checking types, `undefined` properties, and sparse arrays. |
| `toBeDefined()` | Is not `undefined`. |
| `toBeUndefined()` | Is `undefined`. |
| `toBeNull()` | Is `null`. |
| `toBeNaN()` | Is `NaN`. |
| `toBeTruthy()` | Is truthy in a boolean context. |
| `toBeFalsy()` | Is falsy (`false`, `0`, `''`, `null`, `undefined`, `NaN`). |

```javascript
expect({a: 1, b: undefined}).toEqual({a: 1});       // passes
expect({a: 1, b: undefined}).toStrictEqual({a: 1});  // fails — b is present
```

### 4.2 Numbers

| Matcher | Asserts |
|---|---|
| `toBeGreaterThan(n)` | Value `> n` |
| `toBeGreaterThanOrEqual(n)` | Value `>= n` |
| `toBeLessThan(n)` | Value `< n` |
| `toBeLessThanOrEqual(n)` | Value `<= n` |
| `toBeCloseTo(n, precision?)` | Value is within `precision` decimal places of `n` (default precision `2`) |

```javascript
expect(0.1 + 0.2).toBeCloseTo(0.3);     // passes — toBe(0.3) would FAIL
expect(0.1 + 0.2).toBeCloseTo(0.3, 5);  // passes
```

> [!CAUTION]
> Never use `toBe` or `toEqual` to compare floating-point numbers. `0.1 + 0.2 === 0.3` is `false` in JavaScript. Use `toBeCloseTo`.

Both `toBeGreaterThan`, `toBeLessThan`, and friends accept `bigint` values as well as `number`.

### 4.3 Strings

| Matcher | Asserts |
|---|---|
| `toMatch(string \| RegExp)` | String contains the substring, or matches the regular expression |
| `toContain(substring)` | String contains the substring (also works on arrays/iterables) |

```javascript
expect('Hello world').toMatch('world');
expect('Hello world').toMatch(/^Hello/);
```

### 4.4 Arrays, iterables, and objects

| Matcher | Asserts |
|---|---|
| `toContain(item)` | Array/Set/string contains `item` (uses `===`) |
| `toContainEqual(item)` | Array/iterable contains an item deeply equal to `item` |
| `toHaveLength(n)` | Value has a `.length` of `n` |
| `toHaveProperty(keyPath, value?)` | Object has the property at `keyPath`; optionally equal to `value` |
| `toMatchObject(subset)` | Object matches the given subset of properties |
| `toBeInstanceOf(Class)` | Value is an `instanceof Class` |

```javascript
expect(['a', 'b']).toContain('a');
expect([{id: 1}]).toContainEqual({id: 1});
expect({a: {b: 20}}).toHaveProperty('a.b', 20);
expect({name: 'Ada', age: 36}).toMatchObject({name: 'Ada'});
expect(new Date()).toBeInstanceOf(Date);
```

### 4.5 Exceptions

`toThrow` asserts that a function throws when called. **You must wrap the call in a function** so Jest can catch the error:

```javascript
expect(() => parse('')).toThrow();
expect(() => parse('')).toThrow('empty input');     // message contains substring
expect(() => parse('')).toThrow(/empty/);           // message matches regex
expect(() => parse('')).toThrow(SyntaxError);        // error is instance of class
```

> [!WARNING]
> `expect(parse('')).toThrow()` (without the arrow function) does not work — the call happens immediately and the error escapes before Jest can observe it. Always pass `() => parse('')`.

### 4.6 Mock function matchers

These matchers work on mock functions (see [Section 5](#5-mock-functions)):

| Matcher | Asserts the mock… |
|---|---|
| `toHaveBeenCalled()` | Was called at least once |
| `toHaveBeenCalledTimes(n)` | Was called exactly `n` times |
| `toHaveBeenCalledWith(...args)` | Was called at least once with the given arguments |
| `toHaveBeenLastCalledWith(...args)` | Was last called with the given arguments |
| `toHaveBeenNthCalledWith(n, ...args)` | The `n`-th call had the given arguments (1-based) |
| `toHaveReturned()` | Returned (without throwing) at least once |
| `toHaveReturnedTimes(n)` | Returned successfully exactly `n` times |
| `toHaveReturnedWith(value)` | Returned `value` from at least one call |
| `toHaveLastReturnedWith(value)` | Last successful return was `value` |
| `toHaveNthReturnedWith(n, value)` | The `n`-th call returned `value` |

```javascript
const fn = jest.fn();
fn('hello');
expect(fn).toHaveBeenCalledWith('hello');
expect(fn).toHaveBeenCalledTimes(1);
```

### 4.7 Snapshot matchers

| Matcher | Behavior |
|---|---|
| `toMatchSnapshot()` | Compares against a stored snapshot in a `__snapshots__` file |
| `toMatchInlineSnapshot()` | Compares against a snapshot written inline in the test file |
| `toThrowErrorMatchingSnapshot()` | Snapshots the message of a thrown error |
| `toThrowErrorMatchingInlineSnapshot()` | Inline variant of the above |

See [Section 6](#6-snapshot-testing) for the full workflow.

### 4.8 Asymmetric matchers

When you don't know (or don't care about) an exact value, use an asymmetric matcher as part of a larger assertion. They are available as static methods on `expect`:

| Matcher | Matches |
|---|---|
| `expect.anything()` | Any value except `null` or `undefined` |
| `expect.any(Constructor)` | Any value created by `Constructor` (e.g. `expect.any(Number)`) |
| `expect.arrayContaining([...])` | An array containing all listed elements |
| `expect.objectContaining({...})` | An object with at least the listed properties |
| `expect.stringContaining(str)` | A string containing `str` |
| `expect.stringMatching(regexp)` | A string matching the regular expression |
| `expect.closeTo(number, precision?)` | A number close to `number` |

Each also has a negated form: `expect.not.arrayContaining`, `expect.not.objectContaining`, `expect.not.stringContaining`, `expect.not.stringMatching`, `expect.not.closeTo`.

```javascript
expect(user).toEqual({
  id: expect.any(Number),
  name: expect.stringContaining('Ada'),
  roles: expect.arrayContaining(['admin']),
  createdAt: expect.anything(),
});
```

### 4.9 Assertion-count helpers and custom matchers

| Method | Purpose |
|---|---|
| `expect.assertions(n)` | Verify that exactly `n` assertions are called during a test |
| `expect.hasAssertions()` | Verify that at least one assertion is called |
| `expect.extend({...})` | Register custom matchers |
| `expect.addEqualityTesters([...])` | Add custom equality logic used by `toEqual` and friends |

`expect.assertions` is especially valuable in asynchronous tests, where it guarantees a callback actually ran:

```javascript
test('the callback fires', () => {
  expect.assertions(1);
  return fetchData().then(data => {
    expect(data).toBe('peanut butter');
  });
});
```

You can teach Jest new matchers with `expect.extend`:

```javascript
expect.extend({
  toBeWithinRange(received, floor, ceiling) {
    const pass = received >= floor && received <= ceiling;
    return {
      pass,
      message: () =>
        `expected ${received} ${pass ? 'not ' : ''}to be within ${floor}–${ceiling}`,
    };
  },
});

test('range', () => {
  expect(100).toBeWithinRange(90, 110);
});
```

---

## 5. Mock Functions

Mocks let you replace real implementations, observe how functions are called, and control return values.

### 5.1 Creating a mock with `jest.fn()`

```javascript
const callback = jest.fn();
[1, 2, 3].forEach(callback);

expect(callback).toHaveBeenCalledTimes(3);
expect(callback).toHaveBeenNthCalledWith(1, 1, 0, [1, 2, 3]);
```

Every mock records its calls on a `.mock` property:

```javascript
callback.mock.calls;    // array of argument arrays for each call
callback.mock.results;  // array of {type, value} for each return/throw
callback.mock.instances;
callback.mock.contexts;
callback.mock.lastCall;  // arguments of the most recent call
```

### 5.2 Controlling return values and implementations

A mock function exposes a fluent API to control its behavior. These are the methods Jest provides on every mock:

| Method | Effect |
|---|---|
| `mockReturnValue(value)` | Always return `value` |
| `mockReturnValueOnce(value)` | Return `value` for the next call only (queueable) |
| `mockResolvedValue(value)` | Return a Promise resolving to `value` |
| `mockResolvedValueOnce(value)` | One-shot resolved value |
| `mockRejectedValue(value)` | Return a Promise rejecting with `value` |
| `mockRejectedValueOnce(value)` | One-shot rejected value |
| `mockImplementation(fn)` | Use `fn` as the implementation |
| `mockImplementationOnce(fn)` | Use `fn` for the next call only |
| `mockReturnThis()` | Return the `this` context |
| `withImplementation(fn, callback)` | Use `fn` only for the duration of `callback` |
| `mockName(name)` | Set a name shown in error messages |
| `getMockName()` | Read the mock's name |
| `mockClear()` | Reset `.mock.calls`, `.results`, `.instances`, `.contexts` |
| `mockReset()` | `mockClear()` **plus** remove any implementation/return values |
| `mockRestore()` | `mockReset()` **plus** restore the original (non-mocked) implementation |

```javascript
const fn = jest.fn();
fn.mockReturnValueOnce(10).mockReturnValueOnce(20).mockReturnValue(0);

fn(); // 10
fn(); // 20
fn(); // 0
fn(); // 0

const fetchUser = jest.fn().mockResolvedValue({name: 'Ada'});
await expect(fetchUser()).resolves.toEqual({name: 'Ada'});
```

> [!NOTE]
> `mockClear`, `mockReset`, and `mockRestore` form a ladder of increasing aggressiveness: clear wipes call history, reset also drops behavior, restore also brings back the real function (only meaningful for spies created with `jest.spyOn`).

### 5.3 Spying with `jest.spyOn`

`jest.spyOn` wraps an existing method so you can observe it while keeping (or replacing) its behavior:

```javascript
const video = {play: () => true};
const spy = jest.spyOn(video, 'play');

video.play();
expect(spy).toHaveBeenCalled();

spy.mockRestore();  // restore the original method
```

### 5.4 Mocking modules with `jest.mock`

Replace an entire module with an automatic mock, or provide a factory:

```javascript
// Automatic mock — every export becomes a jest.fn()
jest.mock('./api');

// Factory mock — full control
jest.mock('./api', () => ({
  fetchUser: jest.fn().mockResolvedValue({name: 'Ada'}),
}));

import {fetchUser} from './api';

test('uses the mocked module', async () => {
  expect(await fetchUser()).toEqual({name: 'Ada'});
});
```

To use the real module inside a test, call `jest.requireActual('./api')`. Related module-mocking helpers on the `jest` object are listed in [Section 9.2](#92-the-jest-object).

### 5.5 Resetting mocks between tests

Rather than calling reset methods manually, you can have Jest do it automatically before every test via configuration:

| Config / CLI option | Equivalent manual call |
|---|---|
| `clearMocks: true` / `--clearMocks` | `jest.clearAllMocks()` before each test |
| `resetMocks: true` / `--resetMocks` | `jest.resetAllMocks()` before each test |
| `restoreMocks: true` / `--restoreMocks` | `jest.restoreAllMocks()` before each test |

> [!TIP]
> `restoreMocks: true` is a good default for projects that use `jest.spyOn` heavily — it guarantees every spy is torn down between tests so state never leaks.

---

## 6. Snapshot Testing

Snapshot tests capture the rendered output of a value and fail if it changes unexpectedly — ideal for serializable structures like component trees, API responses, or large objects.

### 6.1 Writing a snapshot test

```javascript
test('renders correctly', () => {
  const tree = renderToJSON(<Button label="Submit" />);
  expect(tree).toMatchSnapshot();
});
```

The first run writes a `__snapshots__/<file>.snap` file next to your test. Every subsequent run compares against it. If the output changes:

```text
 FAIL  src/Button.test.js
  ✕ renders correctly

  - Snapshot  - 1
  + Received  + 1

    <button>
  -   Submit
  +   Send
    </button>
```

### 6.2 Updating snapshots

When a change is intentional, re-record the snapshots:

```bash
npx jest --updateSnapshot
# or the short alias
npx jest -u
```

You can scope the update to specific tests by combining with `--testNamePattern`:

```bash
npx jest -u -t "renders correctly"
```

### 6.3 Inline snapshots

Inline snapshots are written directly into your test file (Jest fills the empty string on first run):

```javascript
test('inline', () => {
  expect(user).toMatchInlineSnapshot();
  // After first run Jest rewrites this to:
  // expect(user).toMatchInlineSnapshot(`{ "name": "Ada" }`);
});
```

> [!NOTE]
> Inline snapshots require the `prettier` package to format the written value. The module used is controlled by the `prettierPath` configuration option (default `"prettier"`).

### 6.4 Property matchers in snapshots

For values with non-deterministic fields (timestamps, generated IDs), pass a shape of asymmetric matchers so those fields don't break the snapshot:

```javascript
expect(user).toMatchSnapshot({
  id: expect.any(Number),
  createdAt: expect.any(Date),
});
```

> [!CAUTION]
> Commit your `__snapshots__` directory to version control. Snapshots are part of your test suite — a reviewer should see snapshot changes in the diff. In CI, Jest refuses to write new snapshots by default (see `--ci`) so an obsolete or missing snapshot fails the build instead of silently passing.

---

## 7. Testing Asynchronous Code

Jest supports four idioms for asynchronous tests. Pick whichever reads best.

### 7.1 async / await (recommended)

```javascript
test('fetches the user', async () => {
  const user = await fetchUser(1);
  expect(user.name).toBe('Ada');
});
```

### 7.2 Returning a Promise

If you return a Promise from a test, Jest waits for it to settle:

```javascript
test('resolves', () => {
  return fetchUser(1).then(user => {
    expect(user.name).toBe('Ada');
  });
});
```

### 7.3 The `.resolves` / `.rejects` modifiers

Unwrap a Promise inside the assertion itself:

```javascript
await expect(fetchUser(1)).resolves.toEqual({name: 'Ada'});
await expect(fetchUser(-1)).rejects.toThrow('not found');
```

### 7.4 The `done` callback

For callback-style APIs, accept a `done` parameter and call it when finished:

```javascript
test('calls back', done => {
  fetchData((err, data) => {
    try {
      expect(data).toBe('peanut butter');
      done();
    } catch (error) {
      done(error);
    }
  });
});
```

> [!WARNING]
> A common mistake is forgetting to `await` or `return` the Promise. Without it, the test finishes before the assertions run and may report a false pass. Add `expect.assertions(n)` to guard against this.

> [!IMPORTANT]
> By default, each test has a 5000 ms (`testTimeout`) limit. A test that never resolves will fail with `Exceeded timeout of 5000 ms for a test`. Increase it per test with `test('slow', async () => {...}, 10000)` or globally with the `testTimeout` config option.

---

## 8. Fake Timers

Fake timers let you control time so you can test `setTimeout`, `setInterval`, and date-based logic without actually waiting.

```javascript
beforeEach(() => {
  jest.useFakeTimers();
});

afterEach(() => {
  jest.useRealTimers();
});

test('calls the callback after one second', () => {
  const callback = jest.fn();
  setTimeout(callback, 1000);

  expect(callback).not.toHaveBeenCalled();
  jest.advanceTimersByTime(1000);  // fast-forward time
  expect(callback).toHaveBeenCalledTimes(1);
});
```

Common timer-control methods on the `jest` object:

| Method | Effect |
|---|---|
| `jest.useFakeTimers()` | Replace timer functions with controllable fakes |
| `jest.useRealTimers()` | Restore the real timer functions |
| `jest.advanceTimersByTime(ms)` | Advance time by `ms`, running any timers that fire |
| `jest.runAllTimers()` | Run every pending timer (and timers they schedule) |
| `jest.runOnlyPendingTimers()` | Run only the timers currently queued |
| `jest.advanceTimersToNextTimer()` | Advance to the next scheduled timer |
| `jest.clearAllTimers()` | Remove all pending timers |
| `jest.setSystemTime(now)` | Set the mocked current time |
| `jest.getTimerCount()` | Number of pending fake timers |

You can also enable fake timers for the whole project in configuration:

```javascript
// jest.config.js
module.exports = {
  fakeTimers: {enableGlobally: true},
};
```

> [!TIP]
> Async variants exist for promise-based code: `jest.advanceTimersByTimeAsync`, `jest.runAllTimersAsync`, and `jest.runOnlyPendingTimersAsync`. Use them when a timer callback awaits a Promise.

---

## 9. Command-Line Reference

Run Jest with `jest [options] [test path patterns]`. Any non-flag arguments are treated as patterns matched against test file paths:

```bash
jest                      # run everything
jest src/wallet           # run tests whose path contains "src/wallet"
jest --watch              # interactive watch mode
jest --coverage           # run with coverage reporting
```

### 9.1 Everyday options

| Option | Alias | Description |
|---|---|---|
| `--watch` | | Watch files and re-run tests related to changed files |
| `--watchAll` | | Watch files and re-run **all** tests on any change |
| `--coverage` | | Collect and report code-coverage information |
| `--verbose` | | Show each individual test result with the suite hierarchy |
| `--bail` | `-b` | Exit immediately after `n` failing test suites |
| `--testNamePattern <regex>` | `-t` | Run only tests whose name matches the regex |
| `--testPathPatterns <regex>` | | Run only test files whose path matches the regex |
| `--runTestsByPath` | | Treat the provided patterns as exact file paths |
| `--updateSnapshot` | `-u` | Re-record snapshots |
| `--ci` | | CI mode: never write new snapshots unless explicitly requested |
| `--silent` | | Prevent tests from printing through the console |
| `--expand` | `-e` | Show full diffs instead of a patch |
| `--config <path>` | `-c` | Path to a config file, or a JSON config string |

### 9.2 Selecting which tests run

| Option | Alias | Description |
|---|---|---|
| `--onlyChanged` | `-o` | Run only tests related to files changed in the current repo (git/hg) |
| `--changedSince <branch>` | | Run tests related to changes since the given branch |
| `--changedFilesWithAncestor` | | Include changes from the last commit too |
| `--lastCommit` | | Run tests affected by the last commit |
| `--onlyFailures` | `-f` | Run only tests that failed in the previous run |
| `--findRelatedTests <files...>` | | Run tests that cover the given source files |
| `--listTests` | | Print the list of test files Jest would run, then exit |
| `--collectTests` | | Discover and print all test cases as a tree without running them |
| `--selectProjects <names...>` | | Run only the named projects (by `displayName`) |
| `--ignoreProjects <names...>` | | Skip the named projects |
| `--shard <c/n>` | | Run shard `c` of `n` (e.g. `3/5`) for distributing across machines |
| `--passWithNoTests` | | Do not fail when no tests are found |

### 9.3 Execution and performance options

| Option | Alias | Description |
|---|---|---|
| `--runInBand` | `-i` | Run all tests serially in the current process |
| `--maxWorkers <n\|%>` | `-w` | Maximum worker pool size (e.g. `4` or `50%`) |
| `--maxConcurrency <n>` | | Max simultaneous `test.concurrent` tests (default `5`) |
| `--workerThreads` | | Use worker threads instead of child processes |
| `--detectOpenHandles` | | Print remaining open handles preventing exit (implies `--runInBand`) |
| `--detectLeaks` | | **Experimental**: fail tests that leak the global object |
| `--logHeapUsage` | | Log heap usage after each test (use with `--runInBand`) |
| `--forceExit` | | Force Jest to exit after all tests finish |
| `--randomize` | | Shuffle the order of tests within each file |
| `--seed <n>` | | Set the randomization seed (retrievable via `jest.getSeed()`) |
| `--showSeed` | | Print the seed in the result summary |

> [!CAUTION]
> `--runInBand` and `--maxWorkers` cannot be used together — Jest exits with `Both --runInBand and --maxWorkers were specified, only one is allowed.` Likewise, `--onlyChanged`/`--lastCommit`/`--changedSince`/`--changedFilesWithAncestor` cannot be combined with `--watchAll`.

### 9.4 Coverage options

| Option | Description |
|---|---|
| `--coverage` (alias `--collectCoverage`) | Enable coverage collection |
| `--coverageProvider <babel\|v8>` | Choose the instrumentation engine |
| `--coverageDirectory <dir>` | Where to write coverage reports |
| `--coverageReporters <names...>` | Reporters to use (any Istanbul reporter) |
| `--collectCoverageFrom <glob>` | Glob of files to collect coverage from |
| `--coverageThreshold <json>` | Minimum coverage enforcement (fails the run if not met) |

### 9.5 Introspection options

| Option | Description |
|---|---|
| `--showConfig` | Print the resolved Jest config and exit |
| `--debug` | Print debugging info about your config |
| `--clearCache` | Delete the configured cache directory and exit |
| `--version` (alias `-v`) | Print the Jest version |
| `--help` (alias `-h`) | Print the full options list |

> [!TIP]
> Run `jest --showConfig` whenever Jest behaves unexpectedly. It prints the fully-resolved configuration — including every default — so you can see exactly what Jest is using.

---

## 10. Configuring Jest

### 10.1 Where configuration lives

Jest reads configuration from the first of these it finds:

1. A `jest` key in `package.json`
2. A dedicated config file: `jest.config.js`, `jest.config.ts`, `jest.config.mjs`, `jest.config.mts`, `jest.config.cjs`, `jest.config.cts`, or `jest.config.json` (searched in that order)
3. A `--config` path or JSON string passed on the command line

```javascript
// jest.config.js
/** @type {import('jest').Config} */
const config = {
  testEnvironment: 'node',
  verbose: true,
};

module.exports = config;
```

You can also use the `defineConfig` helper for editor autocomplete:

```javascript
const {defineConfig} = require('jest-config');

module.exports = defineConfig({
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
});
```

> [!NOTE]
> `<rootDir>` is a token Jest replaces with your project root in path-valued options. Always prefer `<rootDir>/path` over absolute paths so the config stays portable.

### 10.2 The most common options

These are the options most projects touch. For the full reference — every option, type, and default — see the Admin Guide.

| Option | Default | Purpose |
|---|---|---|
| `testEnvironment` | `"jest-environment-node"` | The environment tests run in (`node` or `jsdom`) |
| `testMatch` | `["**/__tests__/**/*.?([mc])[jt]s?(x)", "**/?(*.)+(spec\|test).?([mc])[jt]s?(x)"]` | Globs for discovering test files |
| `setupFiles` | `[]` | Modules run once before the test framework is installed |
| `setupFilesAfterEnv` | `[]` | Modules run before each test file (after the framework is ready) |
| `moduleNameMapper` | `{}` | Map import paths to modules/stubs (e.g. CSS or asset stubs) |
| `transform` | (babel-jest for JS/TS) | Map file patterns to transformers |
| `collectCoverage` | `false` | Whether to collect coverage |
| `coverageProvider` | `"babel"` | `"babel"` or `"v8"` |
| `clearMocks` | `false` | Clear mock state before each test |
| `verbose` | `false` | Report each individual test |
| `testTimeout` | `5000` | Per-test timeout in milliseconds |
| `maxWorkers` | `"50%"` | Worker pool size |

### 10.3 Choosing a test environment

For backend / Node code, the default `node` environment is correct. For code that touches the DOM (browser code, React components), install and select `jsdom`:

```bash
npm install --save-dev jest-environment-jsdom
```

```javascript
// jest.config.js
module.exports = {testEnvironment: 'jsdom'};
```

You can also set the environment per file with a docblock at the top of the test:

```javascript
/**
 * @jest-environment jsdom
 */
test('uses the DOM', () => {
  document.body.innerHTML = '<div id="root"></div>';
  expect(document.getElementById('root')).not.toBeNull();
});
```

> [!IMPORTANT]
> As of Jest 28, `jest-environment-jsdom` is no longer bundled with Jest — you must install it separately. If you see `Test environment jest-environment-jsdom cannot be found`, run `npm install --save-dev jest-environment-jsdom`.

### 10.4 Coverage configuration

```javascript
// jest.config.js
module.exports = {
  collectCoverage: true,
  coverageProvider: 'v8',
  collectCoverageFrom: ['src/**/*.{js,ts}', '!src/**/*.d.ts'],
  coverageReporters: ['text', 'lcov'],
  coverageThreshold: {
    global: {branches: 80, functions: 80, lines: 80, statements: 80},
  },
};
```

If coverage falls below a threshold, the run fails — useful as a CI gate.

> [!TIP]
> The `v8` provider is faster and needs no Babel instrumentation, using Node's built-in coverage. The `babel` provider (the default) produces more precise results for transpiled code. Try `v8` first; switch to `babel` if a report looks off.

---

## 11. Using Jest with TypeScript

Jest runs TypeScript test files through a transformer. The two common setups:

=== "Babel (babel-jest, zero type-checking)"

    ```bash
    npm install --save-dev babel-jest @babel/core @babel/preset-env @babel/preset-typescript
    ```

    ```javascript
    // babel.config.js
    module.exports = {
      presets: [
        ['@babel/preset-env', {targets: {node: 'current'}}],
        '@babel/preset-typescript',
      ],
    };
    ```

    `babel-jest` is used automatically when a Babel config is present. It strips types but does **not** type-check.

=== "ts-jest (with type-checking)"

    ```bash
    npm install --save-dev ts-jest
    ```

    ```javascript
    // jest.config.js
    module.exports = {
      preset: 'ts-jest',
      testEnvironment: 'node',
    };
    ```

For editor autocomplete on the global `expect`/`jest`/`describe`, install the type packages and add them to your `tsconfig.json` `types`:

```bash
npm install --save-dev @types/jest
```

> [!NOTE]
> `babel-jest` reads the `BABEL_ENV` or `NODE_ENV` environment variable to pick a Babel environment. Jest sets `NODE_ENV` to `"test"` automatically if it is not already set.

---

## 12. Watch Mode

`jest --watch` starts an interactive session that re-runs tests related to files you change. While watching, press a key to filter:

```text
Watch Usage
 › Press a to run all tests.
 › Press f to run only failed tests.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press q to quit watch mode.
 › Press Enter to trigger a test run.
```

| Key | Action |
|---|---|
| `a` | Run all tests |
| `f` | Run only previously-failed tests |
| `o` | Run only tests related to changed files (default in `--watch`) |
| `p` | Filter by filename pattern |
| `t` | Filter by test-name pattern |
| `u` | Update snapshots |
| `q` | Quit |

> [!TIP]
> `--watch` only re-runs tests related to changed files and requires a git or hg repository. If you are not in a VCS repo, use `--watchAll`, which watches everything.

---

## 13. Troubleshooting

Each entry below uses an exact message Jest emits, its cause, and the fix.

### Error: `Both --runInBand and --maxWorkers were specified, only one is allowed.`

**Cause:** You passed both flags (or a script sets one and you added the other). They are mutually exclusive — `--runInBand` means "one process", `--maxWorkers` configures the pool.
**Solution:** Remove one. Use `--runInBand` for serial debugging; use `--maxWorkers` to size the pool.
**Prevention:** Check your `test` script and CI command for a duplicate flag.

### Error: `The --maxWorkers (-w) option requires a number or string to be specified.`

**Cause:** `--maxWorkers` was given without a value.
**Solution:** Provide a value: `jest --maxWorkers 2` or `jest --maxWorkers 50%`.
**Prevention:** If you meant interactive mode, you probably wanted `--watch`.

### Error: `jest: No configuration found for any project.`

**Cause:** Jest could not locate a config file or a `jest` key, and the directory it scanned has no recognizable Jest configuration.
**Solution:** Add a `jest.config.js` (or a `jest` key in `package.json`), or pass `--config`. Run `npm init jest@latest` to scaffold one.
**Prevention:** Keep a config file at your project root.

### Error: `Test environment jest-environment-jsdom cannot be found.`

**Cause:** You set `testEnvironment: 'jsdom'` but the package is not installed (it is no longer bundled since Jest 28).
**Solution:** `npm install --save-dev jest-environment-jsdom`.
**Prevention:** Add `jest-environment-jsdom` to `devDependencies` for any project that tests DOM code.

### Error: `Exceeded timeout of 5000 ms for a test.`

**Cause:** An async test (or hook) did not finish within the default `testTimeout`. Often an un-awaited Promise or a callback that is never called.
**Solution:** `await`/`return` the Promise, call `done()`, or raise the timeout: `test('slow', fn, 10000)` or set `testTimeout` in config.
**Prevention:** Add `expect.assertions(n)` to async tests so a silently-skipped assertion surfaces.

### Warning: `Jest did not exit one second after the test run has completed.`

**Cause:** Asynchronous operations (open sockets, timers, DB connections) were still running after tests finished.
**Solution:** Close resources in `afterAll`/`afterEach`. Diagnose with `jest --detectOpenHandles`.
**Prevention:** Pair every connection/listener with a teardown hook. As a last resort, `--forceExit`.

### Snapshot keeps failing in CI but passes locally

**Cause:** A new or changed snapshot was not committed, or a non-deterministic value (date, random ID) is embedded in the snapshot. In CI (`--ci`) Jest refuses to write new snapshots.
**Solution:** Run `jest -u` locally and commit the `__snapshots__` change. Use property matchers (`expect.any(Date)`) for volatile fields.
**Prevention:** Always commit snapshots; review them in PRs.

### Memory usage grows when upgrading from Jest 29 to 30

**Cause:** A reported behavior (issue #15743) where heap usage increases across runs in some projects.
**Solution:** Run with `--workerIdleMemoryLimit` to recycle workers that exceed a memory budget, and `--logHeapUsage` to identify the leaking suite. Consider `--runInBand` to isolate.
**Prevention:** Tear down large globals in `afterEach`; avoid retaining references across tests.

### Tests don't pick up changes to a mocked module

**Cause:** Module registry caching, or a `jest.mock` factory referencing out-of-scope variables.
**Solution:** Call `jest.resetModules()` between tests, or enable `resetModules: true`. Ensure the factory only references variables prefixed with `mock`.
**Prevention:** Keep mock factories self-contained.

---

## 14. Frequently Asked Questions

**Q: Do I need a configuration file to use Jest?**
No. Jest works with zero configuration. Add a `jest.config.js` only when you need to change a default.

**Q: What's the difference between `toBe` and `toEqual`?**
`toBe` checks reference/primitive identity (`Object.is`). `toEqual` checks deep, recursive value equality. Use `toBe` for primitives and `toEqual` for objects and arrays.

**Q: What's the difference between `toEqual` and `toStrictEqual`?**
`toStrictEqual` additionally fails on type mismatches, `undefined` properties, and sparse-array differences. Use it when those distinctions matter.

**Q: Why does my `toThrow` assertion fail even though the function throws?**
You probably called the function instead of passing it. Use `expect(() => fn()).toThrow()`, not `expect(fn()).toThrow()`.

**Q: How do I run a single test file?**
`jest path/to/file.test.js`, or filter by a path substring: `jest wallet`.

**Q: How do I run a single test by name?**
`jest -t "the test name regex"`.

**Q: How do I update snapshots?**
`jest -u` (or `--updateSnapshot`). Scope with `-t` to a specific test name.

**Q: `it` or `test` — which should I use?**
They are identical aliases. Pick one and be consistent. `it('should …')` reads as a sentence; `test('…')` is plainer.

**Q: How do I test a function that returns a Promise?**
Make the test `async` and `await` the result, or return the Promise, or use `await expect(promise).resolves.toEqual(...)`.

**Q: Why are my tests slow?**
Worker startup, large `jsdom` environments, and un-cached transforms are common causes. Try `--maxWorkers=50%`, the `v8` coverage provider, and ensure `cache` is enabled (it is by default). For a single machine in CI, sharding with `--shard` distributes across runners.

**Q: How do I make Jest fail when no tests are found?**
That is the default. To allow empty runs (e.g. filtered shards), pass `--passWithNoTests`.

**Q: Can I use ES modules (ESM)?**
Yes. Jest supports native ESM. Run Node with `--experimental-vm-modules` and use `extensionsToTreatAsEsm` for non-`.mjs` files. See the Admin Guide for the full setup.

**Q: How do I see exactly what config Jest is using?**
`jest --showConfig` prints the fully-resolved configuration including all defaults.

**Q: Where is Jest's cache stored?**
In your OS temp directory under `jest` (per-user on POSIX systems). Clear it with `jest --clearCache`. Override with `cacheDirectory`.

**Q: How do I run tests for multiple packages in one repo?**
Use the `projects` option (or `--selectProjects` / `--ignoreProjects`) to run several configurations in a single Jest invocation. Each project can have its own environment and settings.

**Q: What replaced `jest --init`?**
The `create-jest` package. Run `npm init jest@latest`.

---

_Generated June 2026 from jestjs/jest at 4c3091b. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
