Pengujian Aplikasi React: Panduan Vitest dan React Testing Library

Pengujian Aplikasi React: Panduan Vitest dan React Testing Library

Mengapa Memilih Vitest Dibandingkan Jest?

Vitest adalah test runner generasi baru berbasis Vite yang menawarkan eksekusi pengujian secara instan (super fast), dukungan native TypeScript & ESM, serta kompatibilitas penuh dengan API Jest.


1. Menulis Unit Test Fungsi Logika

import { describe, it, expect } from 'vitest';
import { calculateReadingTime } from '@/lib/readingTime';

describe('calculateReadingTime', () => {
  it('menghitung waktu baca dengan tepat berdasarkan jumlah kata', () => {
    const sampleContent = new Array(400).fill('kata').join(' ');
    expect(calculateReadingTime(sampleContent, 'id')).toBe('2 mnt baca');
  });
});

2. Integration Testing Komponen React

Gunakan @testing-library/react untuk menguji bagaimana pengguna berinteraksi dengan antarmuka Anda:

import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { Counter } from './Counter';

describe('Counter Component', () => {
  it('meningkatkan nilai hitungan saat tombol diklik', () => {
    render(<Counter />);
    const button = screen.getByRole('button', { name: /tambah/i });
    fireEvent.click(button);
    expect(screen.getByText('Count: 1')).toBeInTheDocument();
  });
});

Kesimpulan

Memiliki cakupan pengujian yang kuat (test coverage) memberikan kepercayaan diri tinggi saat melakukan refactoring kode dan menjamin aplikasi bebas bug sebelum dirilis ke produksi.

Praktik lengkap: dari instalasi sampai pengujian pertama

Contoh berikut menyiapkan pengujian komponen React sinkron dengan DOM simulasi. Gunakan versi Node yang didukung paket terpasang. Jika proyek sudah memiliki konfigurasi Vitest, gabungkan pengaturan ini dengan konfigurasi yang ada agar alias dan plugin proyek tetap dipertahankan.

1. Instal dependensi dan siapkan lingkungan

npm install -D vitest jsdom @vitejs/plugin-react @testing-library/react @testing-library/dom @testing-library/jest-dom @testing-library/user-event
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  test: { environment: 'jsdom', setupFiles: ['./test/setup.ts'] },
});
// test/setup.ts
import '@testing-library/jest-dom/vitest';
import { afterEach } from 'vitest';
import { cleanup } from '@testing-library/react';

afterEach(cleanup);

2. Uji perilaku yang dilihat pengguna

Simpan contoh ini sebagai Counter.test.tsx. Tombol dicari berdasarkan peran dan namanya, kemudian interaksi ditunggu sebelum hasil diperiksa. Pendekatan ini menguji keluaran komponen tanpa bergantung pada nama variabel internal.

// Counter.test.tsx
import { useState } from 'react';
import { describe, expect, it } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}

describe('Counter', () => {
  it('updates the count after a click', async () => {
    const user = userEvent.setup();
    render(<Counter />);
    await user.click(screen.getByRole('button', { name: 'Count: 0' }));
    expect(screen.getByRole('button', { name: 'Count: 1' })).toBeInTheDocument();
  });
});
npx vitest run

Hasil yang diharapkan adalah satu test lulus. Coba hapus pemanggilan setCount untuk memastikan test benar-benar gagal ketika perilaku tombol rusak. Pulihkan kode setelah percobaan.

3. Telusuri kegagalan yang umum

  • document is not defined: pastikan test memakai environment jsdom, bukan hanya lingkungan Node.
  • toBeInTheDocument tidak dikenali: periksa import jest-dom/vitest dan jalur setupFiles.
  • Elemen tidak ditemukan: periksa nama aksesibel tombol dan tunggu operasi asinkron sebelum membuat assertion.

Test ini tidak membuktikan tampilan browser, integrasi database, atau seluruh alur aplikasi bebas bug. Tambahkan pengujian integrasi atau browser untuk perilaku tersebut. Coverage membantu menemukan jalur yang belum dieksekusi, tetapi bukan jaminan kualitas assertion.

Untuk memilih batas logika yang mudah diuji, lanjutkan ke arsitektur frontend.

Referensi: Vitest, React Testing Library, user-event.