Bỏ qua để vào nội dung chính
Migrating From Jest to Vitest: A Practical Step-by-Step Guide

Migrating From Jest to Vitest: A Practical Step-by-Step Guide

Bởi Marcus Bennett
20 thg 3, 20266 phút đọc

Vitest is Jest-compatible but runs on Vite's native ESM pipeline — making it 10-20x faster for most projects. Learn how to migrate without breaking your test suite.

Why Migrate to Vitest?

Jest uses CommonJS and Babel transforms. Vitest runs on Vite's native ESM pipeline with esbuild — the same toolchain as your app. The result: no transform configuration headaches for ES modules, TypeScript support out of the box, and 10-20x faster test runs on most projects.

Vitest is also Jest-compatible: most tests require zero or minimal changes.

Installation

npm install --save-dev vitest @vitest/ui @vitest/coverage-v8

# If you use React Testing Library
npm install --save-dev @testing-library/react @testing-library/jest-dom

# Remove Jest (optional, can run both during migration)
npm uninstall jest babel-jest jest-environment-jsdom

Vitest Config

// vitest.config.ts
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,        // avoids importing describe, test, expect everywhere
    environment: 'jsdom', // browser-like environment
    setupFiles: ['./tests/setup.ts'],
    coverage: {
      provider: 'v8',
      reporter: ['text', 'html'],
      exclude: ['node_modules', 'tests/setup.ts']
    },
    alias: {
      '@': path.resolve(__dirname, './src')
    }
  },
});
// tests/setup.ts
import '@testing-library/jest-dom';
// Any other global setup (MSW, etc.)

API Compatibility

Most Jest tests work without changes. Common ones that need attention:

// Jest                         // Vitest equivalent
import { jest } from...       // import { vi } from 'vitest'
jest.fn()                     // vi.fn()
jest.spyOn(obj, 'method')    // vi.spyOn(obj, 'method')
jest.mock('./module')         // vi.mock('./module')
jest.useFakeTimers()          // vi.useFakeTimers()
jest.useRealTimers()          // vi.useRealTimers()
jest.resetAllMocks()          // vi.resetAllMocks()

Inline Snapshots Work the Same

// This Jest syntax works identically in Vitest
test('renders correctly', () => {
  const { container } = render(<Button>Click</Button>);
  expect(container).toMatchSnapshot();
});

Update package.json Scripts

{
  "scripts": {
    "test": "vitest",
    "test:run": "vitest run",
    "test:ui": "vitest --ui",
    "test:coverage": "vitest run --coverage",
    "test:watch": "vitest --watch"
  }
}

Vitest-Specific Wins

Beyond speed, Vitest adds features Jest lacks:

  • In-source testing: write tests next to the code they test in if (import.meta.vitest) blocks
  • Browser mode: run tests in a real browser like Playwright CT
  • Vitest UI: beautiful visual test runner UI at localhost:51204
  • Concurrent tests: run test files in parallel without configuration

Common Migration Issues

  • __mocks__ folder: works the same as Jest
  • Module resolution: configure aliases in vitest.config.ts matching your tsconfig paths
  • Globals: add "types": ["vitest/globals"] to tsconfig to avoid type errors when using globals mode

Không spam, hủy đăng ký bất kỳ lúc nào.

Bài viết liên quan