Skip to content

Tiêu chuẩn Unit Test cho Frontend với Vitest

Lưu ý

Tiêu chuẩn này sẽ được triển khai tuỳ vào từng dự án khi tích hợp framework và không mang tính bắt buộc.

Đây là tiêu chuẩn chung để viết Unit Test cho các dự án Frontend (ví dụ: React, Vue), sử dụng Vitest làm testing framework chính. Mục tiêu là đảm bảo các component và logic giao diện hoạt động đúng như mong đợi, dễ bảo trì và mở rộng.

Tại sao chọn Vitest?

  • Tốc độ cao: Được xây dựng trên nền tảng Vite, cho tốc độ thực thi test cực nhanh.
  • Tích hợp liền mạch: Dễ dàng tích hợp với các dự án sử dụng Vite mà không cần cấu hình phức tạp.
  • API quen thuộc: Sử dụng API tương tự Jest, giúp lập trình viên dễ dàng chuyển đổi và sử dụng.
  • Hỗ trợ TypeScript/JSX: Tích hợp sẵn mà không cần cài đặt thêm.

Nguyên tắc viết Test

  1. Đơn giản và rõ ràng: Mỗi test case chỉ nên kiểm tra một hành vi duy nhất. Tên test (it hoặc test) phải mô tả rõ ràng những gì nó đang kiểm tra.
  2. Tập trung vào hành vi: Kiểm tra output của component dựa trên input (props) và tương tác của người dùng, thay vì kiểm tra chi tiết triển khai bên trong (implementation details).
  3. Sử dụng Mocking: Mock các dependencies bên ngoài như API requests, modules, hoặc timers để đảm bảo test chạy nhanh, ổn định và không phụ thuộc vào các dịch vụ bên ngoài.
  4. Tổ chức file test: Đặt file test (ví dụ: *.test.tsx, *.spec.ts) ngay bên cạnh file component mà nó kiểm thử để dễ dàng tìm kiếm và quản lý.

Ví dụ cơ bản (React)

tsx
import { useState } from 'react';

export function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <span>{count}</span>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}
tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { Counter } from './Counter';

describe('Counter', () => {
  it('should render with initial count of 0', () => {
    render(<Counter />);
    expect(screen.getByText('0')).toBeInTheDocument();
  });

  it('should increment count when button is clicked', () => {
    render(<Counter />);
    const button = screen.getByText('Increment');
    fireEvent.click(button);
    expect(screen.getByText('1')).toBeInTheDocument();
  });
});