Thursday

19-06-2025 Vol 19

Jest – Testing with React and React Testing Library: Useful APIs

Jest dan React Testing Library: Panduan Lengkap API Berguna untuk Pengujian React

Pendahuluan

Dalam dunia pengembangan web modern, pengujian adalah bagian penting dari proses pengembangan. Pengujian memastikan bahwa aplikasi Anda berfungsi seperti yang diharapkan dan membantu mencegah bug dan regresi. Untuk aplikasi React, Jest dan React Testing Library (RTL) adalah dua alat populer yang digunakan untuk menulis pengujian yang efektif. Artikel ini akan membahas berbagai API berguna yang disediakan oleh Jest dan RTL, memungkinkan Anda menulis pengujian yang kuat dan dapat diandalkan untuk komponen React Anda.

Tujuan dari panduan ini adalah untuk menyediakan referensi komprehensif untuk menggunakan Jest dan React Testing Library secara efektif, berfokus pada API yang paling berguna yang akan membantu Anda meningkatkan strategi pengujian Anda.

Mengapa Menggunakan Jest dan React Testing Library?

Sebelum kita menyelami API, mari kita pahami mengapa Jest dan React Testing Library adalah pilihan yang baik untuk pengujian React:

  1. Jest: Jest adalah framework pengujian JavaScript yang dibuat oleh Facebook. Ia menawarkan pengalaman “zero-configuration” dan menyediakan semua yang Anda butuhkan untuk menulis, menjalankan, dan melakukan debug pengujian.
  2. React Testing Library: React Testing Library adalah pustaka yang berfokus pada pengujian komponen dari perspektif pengguna. Ia mendorong Anda untuk menulis pengujian yang berinteraksi dengan komponen Anda seperti pengguna biasa, bukan berfokus pada detail implementasi internal.

Kombinasi Jest dan RTL menghasilkan lingkungan pengujian yang kuat dan mudah digunakan yang mempromosikan praktik pengujian yang baik.

Bagian 1: API Jest Penting

Jest menyediakan berbagai API untuk menulis dan menjalankan pengujian. Bagian ini akan membahas API Jest yang paling berguna:

1.1. Fungsi Global Jest

Jest menyediakan beberapa fungsi global yang tersedia di semua file pengujian Anda. Ini adalah blok bangunan untuk menulis pengujian:

  • describe(name, fn): Membuat blok pengujian yang mengelompokkan pengujian terkait. Ini membantu mengatur pengujian Anda dan membuatnya lebih mudah dibaca.
  • it(name, fn) atau test(name, fn): Mendefinisikan pengujian individu. Parameter name adalah deskripsi pengujian, dan fn adalah fungsi yang berisi kode pengujian.
  • expect(value): Memulai rantai pernyataan. Ini digunakan untuk membuat pernyataan tentang kode Anda.
  • beforeEach(fn): Menjalankan fungsi yang ditentukan sebelum setiap pengujian dalam blok describe. Berguna untuk menyiapkan lingkungan pengujian.
  • afterEach(fn): Menjalankan fungsi yang ditentukan setelah setiap pengujian dalam blok describe. Berguna untuk membersihkan lingkungan pengujian.
  • beforeAll(fn): Menjalankan fungsi yang ditentukan sekali sebelum semua pengujian dalam blok describe. Berguna untuk menyiapkan data atau sumber daya global.
  • afterAll(fn): Menjalankan fungsi yang ditentukan sekali setelah semua pengujian dalam blok describe. Berguna untuk membersihkan data atau sumber daya global.

Contoh:


describe('MyComponent', () => {
let component;

beforeEach(() => {
component = ;
});

it('renders correctly', () => {
// Kode pengujian disini
});

it('handles user input', () => {
// Kode pengujian disini
});
});

1.2. Matchers Jest

Matchers digunakan dengan fungsi expect untuk membuat pernyataan. Jest menyediakan berbagai matchers untuk pengujian yang berbeda:

  • toBe(value): Memeriksa kesetaraan yang ketat (===).
  • toEqual(value): Memeriksa kesetaraan yang mendalam. Ini memeriksa bahwa dua objek memiliki properti yang sama dan nilai yang sama.
  • toBeNull(): Memeriksa apakah nilainya adalah null.
  • toBeUndefined(): Memeriksa apakah nilainya adalah undefined.
  • toBeDefined(): Memeriksa apakah nilainya terdefinisi (tidak undefined).
  • toBeTruthy(): Memeriksa apakah nilainya adalah “truthy” (true, bukan null, bukan undefined, bukan 0, bukan false, bukan '').
  • toBeFalsy(): Memeriksa apakah nilainya adalah “falsy” (false, null, undefined, 0, '').
  • toBeGreaterThan(number): Memeriksa apakah nilainya lebih besar dari angka yang diberikan.
  • toBeLessThan(number): Memeriksa apakah nilainya kurang dari angka yang diberikan.
  • toBeGreaterThanOrEqual(number): Memeriksa apakah nilainya lebih besar dari atau sama dengan angka yang diberikan.
  • toBeLessThanOrEqual(number): Memeriksa apakah nilainya kurang dari atau sama dengan angka yang diberikan.
  • toBeCloseTo(number, numDigits?): Membandingkan angka floating-point. Parameter opsional numDigits menentukan jumlah angka desimal untuk dibandingkan.
  • toContain(item): Memeriksa apakah sebuah array berisi item tertentu.
  • toContainEqual(item): Memeriksa apakah sebuah array berisi item yang sama dengan item tertentu (kesetaraan mendalam).
  • toHaveBeenCalled(): Memeriksa apakah fungsi telah dipanggil.
  • toHaveBeenCalledTimes(number): Memeriksa apakah fungsi telah dipanggil sejumlah tertentu kali.
  • toHaveBeenCalledWith(...args): Memeriksa apakah fungsi telah dipanggil dengan argumen tertentu.
  • toHaveBeenLastCalledWith(...args): Memeriksa apakah fungsi telah dipanggil terakhir kali dengan argumen tertentu.
  • toHaveBeenNthCalledWith(nthCall, ...args): Memeriksa apakah fungsi telah dipanggil untuk panggilan ke-n dengan argumen tertentu.
  • toHaveReturned(): Memeriksa apakah fungsi telah dikembalikan.
  • toHaveReturnedTimes(number): Memeriksa apakah fungsi telah dikembalikan sejumlah tertentu kali.
  • toHaveReturnedWith(value): Memeriksa apakah fungsi telah dikembalikan dengan nilai tertentu.
  • toHaveLastReturnedWith(value): Memeriksa apakah fungsi telah dikembalikan terakhir kali dengan nilai tertentu.
  • toHaveNthReturnedWith(nthCall, value): Memeriksa apakah fungsi telah dikembalikan untuk panggilan ke-n dengan nilai tertentu.
  • toThrow(error?): Memeriksa apakah fungsi melempar kesalahan. Parameter opsional error dapat berupa string, objek kesalahan, atau konstruktor kesalahan.
  • toMatch(regexp): Memeriksa apakah string cocok dengan ekspresi reguler.
  • toMatchObject(object): Memeriksa apakah sebuah objek cocok dengan subset properti dari objek yang diberikan.
  • toHaveProperty(keyPath, value?): Memeriksa apakah sebuah objek memiliki properti dengan jalur kunci yang ditentukan. Parameter opsional value memeriksa apakah properti tersebut memiliki nilai tertentu.
  • instanceof(Class): Memeriksa apakah objek adalah instance dari kelas tertentu.

Contoh:


it('adds two numbers correctly', () => {
expect(2 + 2).toBe(4);
});

it('calls a function', () => {
const mockFn = jest.fn();
mockFn();
expect(mockFn).toHaveBeenCalled();
});

1.3. Mock Functions (jest.fn())

Mock functions sangat berguna untuk menguji interaksi antar komponen. Mereka memungkinkan Anda memantau bagaimana fungsi dipanggil dan apa yang mereka kembalikan.

Contoh:


it('calls the onSubmit function when the form is submitted', () => {
const onSubmit = jest.fn();
const { getByText } = render();
const submitButton = getByText('Submit');
fireEvent.click(submitButton);
expect(onSubmit).toHaveBeenCalledTimes(1);
});

1.4. Timers Mocking (jest.useFakeTimers())

Timers mocking berguna untuk menguji kode yang menggunakan fungsi setTimeout atau setInterval. Anda dapat mengontrol berjalannya waktu dalam pengujian Anda.

Contoh:


it('updates the state after a delay', () => {
jest.useFakeTimers();
const { getByText } = render();
expect(getByText('Initial Value')).toBeInTheDocument();
jest.advanceTimersByTime(1000); // Majukan timers 1 detik
expect(getByText('Updated Value')).toBeInTheDocument();
});

1.5. Snapshot Testing (toMatchSnapshot())

Pengujian snapshot memungkinkan Anda menyimpan output komponen dan membandingkannya dengan output di masa mendatang. Ini berguna untuk mendeteksi perubahan tak terduga dalam antarmuka pengguna.

Contoh:


it('renders correctly', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});

1.6. Modul Mocking (jest.mock())

Modul mocking memungkinkan Anda mengganti modul dengan implementasi mock. Ini berguna untuk mengisolasi komponen Anda dari dependensi eksternal.

Contoh:


jest.mock('./api'); // Mock modul api.js

it('fetches data correctly', async () => {
api.fetchData.mockResolvedValue({ data: 'Mock Data' }); // Mock fungsi fetchData

const { getByText } = render();
await waitFor(() => expect(getByText('Mock Data')).toBeInTheDocument());
});

Bagian 2: API React Testing Library Penting

React Testing Library menyediakan serangkaian API yang memungkinkan Anda berinteraksi dengan komponen React Anda seperti pengguna biasa. Bagian ini akan membahas API RTL yang paling berguna.

2.1. Render (render())

Fungsi render digunakan untuk me-render komponen React ke dalam DOM virtual untuk pengujian.

Contoh:


import { render } from '@testing-library/react';
import MyComponent from './MyComponent';

it('renders without crashing', () => {
render();
});

2.2. Query Selectors

React Testing Library menyediakan berbagai query selectors untuk menemukan elemen di DOM:

  • getByRole(role, options?): Menemukan elemen dengan peran ARIA tertentu. Ini adalah cara yang direkomendasikan untuk menemukan elemen karena berfokus pada aksesibilitas.
  • getByLabelText(text, options?): Menemukan elemen input berdasarkan teks label yang terkait.
  • getByPlaceholderText(text, options?): Menemukan elemen input berdasarkan teks placeholder-nya.
  • getByText(text, options?): Menemukan elemen yang berisi teks yang diberikan.
  • getByDisplayValue(value, options?): Menemukan elemen input berdasarkan nilai yang ditampilkan.
  • getByAltText(text, options?): Menemukan elemen gambar berdasarkan teks alternatif-nya.
  • getByTitle(text, options?): Menemukan elemen berdasarkan atribut judul-nya.
  • getAllByRole(role, options?): Menemukan semua elemen dengan peran ARIA tertentu.
  • getAllByLabelText(text, options?): Menemukan semua elemen input berdasarkan teks label yang terkait.
  • getAllByPlaceholderText(text, options?): Menemukan semua elemen input berdasarkan teks placeholder-nya.
  • getAllByText(text, options?): Menemukan semua elemen yang berisi teks yang diberikan.
  • getAllByDisplayValue(value, options?): Menemukan semua elemen input berdasarkan nilai yang ditampilkan.
  • getAllByAltText(text, options?): Menemukan semua elemen gambar berdasarkan teks alternatif-nya.
  • getAllByTitle(text, options?): Menemukan semua elemen berdasarkan atribut judul-nya.
  • queryByRole(role, options?): Menemukan elemen dengan peran ARIA tertentu. Mengembalikan null jika tidak ditemukan.
  • queryByLabelText(text, options?): Menemukan elemen input berdasarkan teks label yang terkait. Mengembalikan null jika tidak ditemukan.
  • queryByPlaceholderText(text, options?): Menemukan elemen input berdasarkan teks placeholder-nya. Mengembalikan null jika tidak ditemukan.
  • queryByText(text, options?): Menemukan elemen yang berisi teks yang diberikan. Mengembalikan null jika tidak ditemukan.
  • queryByDisplayValue(value, options?): Menemukan elemen input berdasarkan nilai yang ditampilkan. Mengembalikan null jika tidak ditemukan.
  • queryByAltText(text, options?): Menemukan elemen gambar berdasarkan teks alternatif-nya. Mengembalikan null jika tidak ditemukan.
  • queryByTitle(text, options?): Menemukan elemen berdasarkan atribut judul-nya. Mengembalikan null jika tidak ditemukan.
  • queryAllByRole(role, options?): Menemukan semua elemen dengan peran ARIA tertentu. Mengembalikan array kosong jika tidak ditemukan.
  • queryAllByLabelText(text, options?): Menemukan semua elemen input berdasarkan teks label yang terkait. Mengembalikan array kosong jika tidak ditemukan.
  • queryAllByPlaceholderText(text, options?): Menemukan semua elemen input berdasarkan teks placeholder-nya. Mengembalikan array kosong jika tidak ditemukan.
  • queryAllByText(text, options?): Menemukan semua elemen yang berisi teks yang diberikan. Mengembalikan array kosong jika tidak ditemukan.
  • queryAllByDisplayValue(value, options?): Menemukan semua elemen input berdasarkan nilai yang ditampilkan. Mengembalikan array kosong jika tidak ditemukan.
  • queryAllByAltText(text, options?): Menemukan semua elemen gambar berdasarkan teks alternatif-nya. Mengembalikan array kosong jika tidak ditemukan.
  • queryAllByTitle(text, options?): Menemukan semua elemen berdasarkan atribut judul-nya. Mengembalikan array kosong jika tidak ditemukan.
  • find** (asinkron): Menemukan elemen secara asinkron, menunggu elemen muncul di DOM. Ini berguna untuk pengujian yang melibatkan pembaruan asinkron. Misalnya, findByRole, findByText, dll.

Perbedaan utama antara getBy*, queryBy*, dan findAllBy* adalah perilakunya ketika elemen tidak ditemukan:

  • getBy* akan melempar kesalahan jika elemen tidak ditemukan.
  • queryBy* akan mengembalikan null jika elemen tidak ditemukan.
  • findAllBy* akan melempar kesalahan jika elemen tidak ditemukan.

Fungsi find* adalah versi asinkron dari getBy* yang menunggu elemen muncul di DOM.

Contoh:


import { render, screen, fireEvent } from '@testing-library/react';
import MyComponent from './MyComponent';

it('updates the input value when the user types', () => {
render();
const inputElement = screen.getByRole('textbox'); // Gunakan getByRole
fireEvent.change(inputElement, { target: { value: 'Hello' } });
expect(inputElement.value).toBe('Hello');
});

2.3. FireEvent (fireEvent)

Fungsi fireEvent digunakan untuk mensimulasikan peristiwa pengguna, seperti klik, perubahan, dan pengiriman.

Contoh:


import { render, screen, fireEvent } from '@testing-library/react';
import MyComponent from './MyComponent';

it('calls the onClick function when the button is clicked', () => {
const onClick = jest.fn();
render();
const buttonElement = screen.getByRole('button');
fireEvent.click(buttonElement);
expect(onClick).toHaveBeenCalledTimes(1);
});

2.4. UserEvent (userEvent)

userEvent adalah abstraksi di atas fireEvent yang memberikan simulasi interaksi pengguna yang lebih realistis. Ini menangani detail yang lebih banyak seperti fokus, seleksi, dan input yang lebih kompleks.

Contoh:


import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import MyComponent from './MyComponent';

it('updates the input value when the user types', async () => {
render();
const inputElement = screen.getByRole('textbox');
await userEvent.type(inputElement, 'Hello');
expect(inputElement.value).toBe('Hello');
});

2.5. Wait For (waitFor)

Fungsi waitFor digunakan untuk menunggu pembaruan asinkron terjadi. Ini berguna untuk menguji kode yang melibatkan pemanggilan API atau efek samping lainnya.

Contoh:


import { render, screen, waitFor } from '@testing-library/react';
import MyComponent from './MyComponent';

it('displays the data after it is fetched', async () => {
render();
await waitFor(() => screen.getByText('Data Loaded'));
expect(screen.getByText('Data Loaded')).toBeInTheDocument();
});

2.6. AsFragment (asFragment())

Fungsi `asFragment` mengembalikan representasi DOM dari komponen yang di-render sebagai `DocumentFragment`. Ini berguna untuk pengujian snapshot.

Contoh:


import { render } from '@testing-library/react';
import MyComponent from './MyComponent';

it('renders correctly', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});

Bagian 3: Praktik Terbaik untuk Pengujian React dengan Jest dan RTL

Untuk menulis pengujian yang efektif, ikuti praktik terbaik ini:

  1. Fokus pada Pengujian Perilaku: Gunakan React Testing Library untuk menguji komponen Anda dari perspektif pengguna. Hindari menguji detail implementasi.
  2. Tulis Pengujian yang Kecil dan Terisolasi: Setiap pengujian harus fokus pada aspek tunggal dari komponen Anda.
  3. Gunakan Mock Functions Secara Efektif: Mock functions untuk mengisolasi komponen Anda dan memverifikasi interaksi antar komponen.
  4. Manfaatkan Snapshot Testing dengan Bijak: Gunakan snapshot testing untuk mendeteksi perubahan tak terduga dalam antarmuka pengguna, tetapi pastikan untuk meninjau dan memperbarui snapshot ketika perubahan yang disengaja terjadi.
  5. Jaga Pengujian Anda agar Tetap Terbaca dan Terkelola: Gunakan fungsi describe untuk mengelompokkan pengujian terkait dan berikan nama yang jelas dan deskriptif untuk pengujian Anda.
  6. Uji Edge Cases dan Error Handling: Pastikan untuk menguji bagaimana komponen Anda berperilaku dalam situasi yang tidak terduga, seperti masukan yang tidak valid atau kesalahan API.
  7. Menulis Pengujian Aksesibel: Gunakan query seperti `getByRole` yang mendorong penulisan pengujian yang lebih mudah diakses.

Kesimpulan

Jest dan React Testing Library adalah alat yang ampuh untuk menguji aplikasi React. Dengan memahami API yang disediakan oleh alat-alat ini dan mengikuti praktik terbaik, Anda dapat menulis pengujian yang kuat dan dapat diandalkan yang membantu memastikan kualitas aplikasi Anda. Artikel ini telah memberikan panduan komprehensif untuk API Jest dan RTL yang paling berguna, beserta contoh dan praktik terbaik untuk membantu Anda memulai.

Ingat, pengujian bukan hanya tentang menemukan bug; ini tentang memberikan kepercayaan pada kode Anda dan memfasilitasi perubahan di masa mendatang. Dengan berinvestasi dalam pengujian yang baik, Anda dapat membuat aplikasi yang lebih stabil, mudah dipelihara, dan mudah digunakan.

“`

omcoding

Leave a Reply

Your email address will not be published. Required fields are marked *