Configures and runs Jest - Meta-built batteries-included JS/TS unit framework with built-in `expect`, snapshot testing, mocking (`jest.mock`, `jest.fn`, `jest.spyOn`, manual `__mocks__/`), test environment selection (`jsdom` / `node`), parallel workers, coverage via Istanbul, watch mode, and CI integration via `--ci` flag. Use when the user works with React (CRA / older Next.js) or Node services and needs the most ecosystem-supported JS test framework.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Per jestjs.io/docs/getting-started:
Jest is "a delightful JavaScript Testing Framework with a focus on
simplicity." It bundles expect assertions, snapshot testing,
mocking (no separate Sinon needed), and code coverage in one tool.
Works with TypeScript via babel-jest (faster) or ts-jest (full
type-checking).
This skill targets per-framework lifecycle (configure / run /
mock / coverage / CI) - NOT test code hygiene patterns. For
hygiene (assertion quality / AAA structure / mocking anti-patterns),
see test-code-conventions; test code is reviewed separately.
jest.config.js, jest.config.ts, or jest key in
package.json.For Vite-based projects, prefer vitest-tests
(Vite-native; faster transform-pipeline reuse).
vitest-tests.jest (add ts-jest or babel-jest for TypeScript) and scaffold
config with npm init jest@latest.*.test.js / *.spec.js files using expect matchers; wire
"test": "jest" and run npm test.jest.fn / jest.mock / jest.spyOn and
control time with fake timers (see Mocking).testEnvironment explicitly and add coverageThreshold to gate
coverage; run jest --coverage (see Configuration and Coverage, CI, and ESLint).npx jest --ci --maxWorkers=2 with jest-junit for JUnit XML
(see Coverage, CI, and ESLint).Per jest-start:
npm install --save-dev jest
# or yarn add --dev jest / pnpm add --save-dev jest / bun add --dev jestFor TypeScript, choose one:
# Option A: ts-jest (full type-checking; slower)
npm install --save-dev ts-jest
# Option B: babel-jest (faster; type errors NOT caught - pair with tsc --noEmit in CI)
npm install --save-dev babel-jest @babel/core @babel/preset-env @babel/preset-typescriptPer jest-start babel.config.js for TS via Babel:
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript',
],
};For type definitions, prefer the bundled @jest/globals:
npm install --save-dev @jest/globalsThen import explicitly per jest-start:
import {describe, expect, test} from '@jest/globals';
import {sum} from './sum';This avoids global pollution + is the modern recommendation.
Per jest-start:
// sum.js
function sum(a, b) {
return a + b;
}
module.exports = sum;// sum.test.js
const sum = require('./sum');
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});Wire package.json:
{
"scripts": {
"test": "jest"
}
}Run via npm test.
A Node service function getUser(id) calls fetchUser from ./api-client;
verify it without a live API.
// user-service.test.js
import { getUser } from './user-service';
import { fetchUser } from './api-client';
jest.mock('./api-client');
test('returns the fetched user', async () => {
fetchUser.mockResolvedValue({ id: 1, name: 'Alice' });
await expect(getUser(1)).resolves.toEqual({ id: 1, name: 'Alice' });
expect(fetchUser).toHaveBeenCalledWith(1);
});Run npm test. jest.mock('./api-client') auto-replaces the module so no
network call fires; the test passes when getUser forwards the id and returns
the resolved user.
npm init jest@latest scaffolds a config. Key gotcha: testEnvironment
defaults to jsdom in Jest 26 and earlier but node from Jest 27+, so set it
explicitly. The full jest.config.js reference (coverage collection,
moduleNameMapper path aliases, transform) is in
references/configuration.md.
Jest ships mocking without a separate Sinon: jest.fn() (standalone),
jest.mock('./module') (automatic module mock), jest.spyOn(obj, 'method')
(wrap an existing method), manual mocks in __mocks__/, and fake timers
(jest.useFakeTimers). Patterns and timer control are in
references/mocking.md.
Run jest --coverage (Istanbul) and gate via coverageThreshold. In CI,
--ci fails on missing snapshots instead of writing them and disables
interactive prompts; pair with --maxWorkers=2 on hosted runners and
jest-junit for JUnit XML. The coverage config, GitHub Actions workflow, and
ESLint test-globals setup are in
references/coverage-ci-eslint.md.
| Anti-pattern | Why it fails | Fix |
|---|---|---|
jest.mock at top of file without specific test scope | Module mock leaks across tests; brittle | jest.doMock per-test or move to __mocks__/ (see Mocking) |
--watchAll in CI | Hangs forever | Use --ci (see Coverage, CI, and ESLint) |
| Snapshot-only assertions | Tests pass on every change without semantic verification | Targeted expect() for invariants; snapshots for stable shape only |
Skip --maxWorkers config in CI | Default = #cores; can OOM CI runners | Pin --maxWorkers=2 for typical hosted CI (see Coverage, CI, and ESLint) |
Run TypeScript via babel-jest without separate tsc --noEmit | Type errors silently bypass tests | Pair babel-jest with tsc --noEmit in CI (Step 1) |
vitest-tests on
Vite-based projects (Jest doesn't share dev-server transform).jest-image-snapshot
for visual snapshots.jest.mock at top of file) has subtle ordering
semantics; test code hygiene addressed in qa-test-review.--civitest-tests,
mocha-tests,
ava-tests,
jasmine-tests - sister toolstest-code-conventions (qa-test-review) - test code hygiene (separate from per-framework
lifecycle)