Jest Setup and Configuration
Now that you understand why testing matters, let's set up Jest in a project. We'll cover installation, configuration options, and how to run tests effectively.
Installing Jest
Jest can be installed via npm or yarn. In a new or existing project:
# Using npm
npm install --save-dev jest
# Using yarn
yarn add --dev jest
For TypeScript projects, you'll also need:
npm install --save-dev ts-jest @types/jest
Package.json Configuration
Add a test script to your package.json:
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
}
}
Now you can run tests with:
npm test # Run all tests once
npm run test:watch # Run tests in watch mode (re-runs on file changes)
npm run test:coverage # Run tests and generate coverage report
Jest Configuration File
Jest works with zero configuration for simple projects, but most real projects need some customization. Create a jest.config.js file:
module.exports = {
// The test environment to use
testEnvironment: 'node', // or 'jsdom' for browser-like environment
// File extensions Jest will look for
moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'],
// Pattern to find test files
testMatch: [
'**/__tests__/**/*.[jt]s?(x)',
'**/?(*.)+(spec|test).[jt]s?(x)'
],
// Files to ignore
testPathIgnorePatterns: [
'/node_modules/',
'/dist/'
],
// Coverage configuration
collectCoverageFrom: [
'src/**/*.{js,jsx,ts,tsx}',
'!src/**/*.d.ts'
],
};
For TypeScript projects, add ts-jest configuration:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'],
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
};
Test File Naming Conventions
Jest looks for test files using these patterns by default:
- Files in
__tests__folders:src/__tests__/myFunction.test.js - Files with
.test.jssuffix:src/utils/myFunction.test.js - Files with
.spec.jssuffix:src/utils/myFunction.spec.js
Common project structures:
# Option 1: Tests alongside source files
src/
utils/
formatDate.js
formatDate.test.js
calculateTotal.js
calculateTotal.test.js
# Option 2: Separate __tests__ folders
src/
utils/
formatDate.js
calculateTotal.js
__tests__/
formatDate.test.js
calculateTotal.test.js
# Option 3: Top-level tests folder
src/
utils/
formatDate.js
calculateTotal.js
tests/
utils/
formatDate.test.js
calculateTotal.test.js
Choose the convention that works for your team and stick with it.
Running Tests
Basic Commands
# Run all tests
npm test
# Run tests matching a pattern
npm test -- formatDate
# Run a specific test file
npm test -- src/utils/formatDate.test.js
# Run in watch mode (recommended during development)
npm test -- --watch
Watch Mode Commands
When running in watch mode, Jest provides interactive commands:
a- Run all testsf- Run only failed testsp- Filter by filename patternt- Filter by test name patternq- Quit watch modeEnter- Re-run tests
Watch mode is incredibly useful during development - it re-runs relevant tests whenever you save a file.
Environment Setup
Setup and Teardown Files
For global setup (like database connections), create setup files:
// jest.setup.js
beforeAll(() => {
console.log('Running before all tests');
});
afterAll(() => {
console.log('Running after all tests');
});
Reference it in your config:
// jest.config.js
module.exports = {
setupFilesAfterEnv: ['./jest.setup.js'],
};
Environment Variables
For tests, you often need different environment variables. Create a .env.test file or set them in your config:
// jest.config.js
module.exports = {
testEnvironment: 'node',
globals: {
'process.env': {
NODE_ENV: 'test',
API_URL: 'http://localhost:3000',
},
},
};
Common Configuration Options
Here's a comprehensive configuration with explanations:
// jest.config.js
module.exports = {
// Use jsdom for React/browser testing, node for backend
testEnvironment: 'jsdom',
// Setup files to run before tests
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
// Module path aliases (match your tsconfig/webpack)
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
'\\.(css|less|scss)$': 'identity-obj-proxy',
},
// Transform files with ts-jest or babel
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
'^.+\\.(js|jsx)$': 'babel-jest',
},
// Coverage thresholds (fail if below these)
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
// Verbose output
verbose: true,
// Clear mocks between tests
clearMocks: true,
// Collect coverage from these files
collectCoverageFrom: [
'src/**/*.{js,jsx,ts,tsx}',
'!src/**/*.d.ts',
'!src/index.ts',
],
};
Troubleshooting Common Issues
"Cannot find module" Errors
Usually caused by path aliases. Update moduleNameMapper:
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
}
"SyntaxError: Unexpected token"
Usually means the file isn't being transformed. Update transform:
transform: {
'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
}
Tests Running Slowly
Try these optimizations:
// Run tests in parallel
maxWorkers: '50%',
// Cache transformed files
cache: true,
// Skip coverage during development
// Only run coverage in CI
Key Takeaways
- Install Jest with
npm install --save-dev jest - Configure test scripts in
package.json - Use
jest.config.jsfor project-specific settings - Follow consistent test file naming conventions
- Use watch mode (
--watch) during development - Configure coverage thresholds for code quality
In the next lesson, we'll write your first test and see it pass!

