
Vitest và React Testing Library đang trở thành bộ đôi testing phổ biến nhất cho dự án React hiện đại. Nếu bạn vẫn còn dùng Jest, bài viết này sẽ cho bạn thấy lý do nên chuyển sang Vitest — tốc độ nhanh hơn, cấu hình gần như zero, tương thích hoàn toàn với React Testing Library.
Tại sao chuyển từ Jest sang Vitest?
Jest đã là tiêu chuẩn testing JavaScript nhiều năm, nhưng Vitest mang lại trải nghiệm tốt hơn nhờ:
- Tốc độ cực nhanh: dựa trên Vite, chạy hot module replacement, chỉ re-test file bị thay đổi.
- Cấu hình gần như zero: không cần jest.config.js phức tạp, chỉ cần vài dòng trong
vite.config.ts. - Tương thích Jest API:
describe,it,expect,vi.fn()đều hoạt động y hệt. - TypeScript native: config tự nhận kiểu dữ liệu, không cần
ts-jest.

Cài đặt Vitest cho dự án React
Thêm Vitest vào project React Vite chỉ mất vài phút:
npm install -D vitest @testing-library/react @testing-library/jest-dom
npm install -D @testing-library/user-event jsdom
Sau đó thêm section test vào vite.config.ts:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
globals: true,
setupFiles: './src/test/setup.ts',
},
})
React Testing Library: Test theo cách người dùng thật sự dùng
React Testing Library (RTL) khuyến khích bạn test component từ góc nhìn người dùng — click, type, query theo label chứ không phải implementation detail. Đây là ví dụ test component LoginForm:
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import LoginForm from './LoginForm'
test('submit form with valid credentials', async () => {
render(<LoginForm />)
await userEvent.type(screen.getByLabelText(/email/i), '[email protected]')
await userEvent.type(screen.getByLabelText(/mật khẩu/i), 'secret123')
await userEvent.click(screen.getByRole('button', { name: /đăng nhập/i }))
expect(await screen.findByText(/chào mừng/i)).toBeInTheDocument()
})

So sánh tốc độ Jest vs Vitest
Trên dự án React có 200 test cases, Vitest chạy xong trong khoảng 3-5 giây trong chế độ watch, trong khi Jest cần 15-20 giây cho lần chạy đầu và 8-12 giây khi incremental. Hiệu năng khác biệt rõ rệt khi bạn phải chạy test liên tục trong quá trình phát triển.
Mock và Spy trong Vitest
Vitest cung cấp API vi tương tự Jest nhưng với một số cải tiến:
vi.fn()— mock function có thể kiểm tratoHaveBeenCalled()vi.spyOn()— theo dõi method gốc mà không ghi đèvi.mock()— mock toàn bộ module
vi.mock('./api', () => ({
fetchUser: vi.fn().mockResolvedValue({ name: 'Hung', role: 'admin' }),
}))
Coverage report tích hợp sẵn
Vitest có built-in coverage nhờ @vitest/coverage-v8. Chỉ cần thêm flag --coverage khi chạy:
npx vitest run --coverage
Báo cáo sẽ hiển thị line, function, branch coverage trực quan trong terminal hoặc HTML report. Không cần cấu hình thêm babel-plugin-istanbul hay jest-coverage.
Khi nào nên giữ Jest?
Jest vẫn phù hợp nếu bạn dùng React Native (Metro bundler chưa hỗ trợ Vitest tốt), hoặc project legacy cần migrate từng bước. Tuy nhiên, với dự án React mới khởi tạo bằng Vite, Vitest là lựa chọn tối ưu.
Migrate từ Jest sang Vitest: Mẹo thực tế
Quá trình migrate thường nhẹ nhàng vì API tương thích, nhưng có một vài điểm cần lưu ý:
- Setup files: Cài đặt lại các mock global trong
test/setup.tsthay vìjest.setup.js. - Snapshot testing: Vitest dùng thư viện
@vitest/snapshot, snapshot cũ cần cập nhật lại. - Timer mocks: Thay
jest.useFakeTimers()bằngvi.useFakeTimers(). - Module mocks:
vi.mock()hoạt động ở top-level, không cần factory function như Jest.
Ví dụ migrate một test case:
// Jest
jest.mock('./utils', () => ({
formatDate: jest.fn().mockReturnValue('2025-01-01'),
}));
// Vitest
vi.mock('./utils', () => ({
formatDate: vi.fn().mockReturnValue('2025-01-01'),
}));
Vitest UI: Giao diện trực quan cho testing
Vitest đi kèm UI dashboard chạy bằng npx vitest --ui. Bạn có thể:
- Xem test tree, filter theo tên, trạng thái pass/fail.
- Inspect source code tại dòng bị fail.
- Re-run single test bằng click chuột.
- Xem coverage overlay trực tiếp trên code.
Điều này giúp debug test nhanh hơn nhiều so với terminal output thuần túy, đặc biệt khi test suite lớn.
CI/CD Integration
Vitest tích hợp trực tiếp vào GitHub Actions, GitLab CI hoặc Vercel. Chỉ cần cài đặt Node 18+, chạy npx vitest run trong workflow. Output JSON cho Jest compatibility nên bạn có thể giữ lại cấu hình CI cũ.
Tổng kết
Vitest kết hợp React Testing Library tạo ra workflow testing nhanh, hiện đại và ít friction nhất cho React hiện tại. Tìm hiểu thêm tại vitest.dev và testing-library.com. Bạn có thể migrate từng file mà không cần đổi toàn bộ codebase nhờ tương thích API Jest.
