Kamu menerapkan perubahan UI kecil sebelum makan siang. Terlihat tidak berbahaya. Label tombol berubah, render kondisional diperbarui, dan hook bantuan mengambil cabang baru. Permintaan pull bersih, tinjauan cepat, dan deploy keluar.
Sejam kemudian, dukungan melaporkan bahwa login tidak berfungsi di satu platform. Web terlihat baik. Shell desktop memiliki jalur render ketinggalan. Bangun mobile berperilaku berbeda setelah perubahan async keadaan. Tidak ada yang menangkapnya karena code memiliki tes, tapi tidak tes yang tepat, dan pasti tidak sistem yang dapat diandalkan di sekitar tes tersebut.
Masalah utama dengan melakukan unit testing React di tim produksi adalah menulis beberapa tes yang berhasil bukanlah hal yang sulit. Namun, membuat suatu suite yang masih melindungi Anda selama refactor, peluncuran, patch, dan pengemasan multi-platform adalah bagian yang sulit. render()Mengapa aplikasi React gagal bukan karena tim lupa cara memanggil fungsi, melainkan karena tes mulai mengarah ke detail implementasi, perilaku asyncus disembunyikan, dan CI menganggap tes sebagai sebuah kotak centang bukan sebagai pintu rilis.
Modern unit testing React works when it behaves like a safety system. Fast feedback locally. Deterministic checks in CI. Clear boundaries around what belongs in a unit test and what doesn’t. That matters even more when the same React codebase ships through browsers, Capacitor containers, or Electron shells.
Daftar Isi
- Mengapa Unit Testing React Adalah Jaringan Keamanan Terbaik Anda
- Mengatur Lingkungan Testing Modern React Anda
- Mengapa Menulis Tes Komponen Yang Bermakna
- Menguji Hook-Hook Kustom dan Logika Aplikasi
- Menguasai Teknik-Teknik Lanjutan Mocking dan Async
- Meningkatkan Kualitas dan Strategi Tes
- Integrasi Uji Coba ke Pipa CI/CD Cross-Platform
Mengapa Unit Testing React Adalah Jaringan Keamanan Terbaik Anda
Uji unit mendapatkan keuntungannya ketika mereka menangkap kesalahan yang Anda percaya tidak akan terjadi. Di React, biasanya berarti komponen masih menampilkan, tetapi perilaku yang bergantung pada pengguna telah berubah. Tombol yang dinonaktifkan menjadi dapat diklik. Status muatan yang sedang dimuat tidak pernah hilang. Pesan pengganti hilang setelah refactor. Kesalahan-kesalahan itu kecil dalam code dan mahal dalam produksi.
Uji coba React berubah dalam cara yang penting ketika React Testing Library menjadi model utama untuk menguji perilaku bukan internal, mengarahkan tim ke uji coba yang mengambang perilaku pengguna bukan atribut komponen atau keadaan, seperti yang terlihat dalam panduan uji coba React Native di Panduan Uji Coba React Native. Perubahan itu penting karena React code selalu berubah. Hooks berpindah. Komponen terpecah. Konteks diperkenalkan. Uji coba yang terkait dengan struktur internal rusak selama refactor yang sehat. Uji coba yang terkait dengan perilaku yang dapat dilihat biasanya bertahan.
Apa yang harus dilindungi oleh unit test
Unit test yang baik melindungi satu kontrak kecil:
- Output yang dirender: Apakah pengguna melihat teks, label, status, atau fallback yang benar?
- Perilaku interaksi: Apakah klik, ketik, atau toggle mengubah UI dengan benar?
- Pengelolaan batas: Apakah komponen berperilaku dengan benar ketika menerima input yang diharapkan, data yang hilang, atau jalur error?
Unit test yang lemah melindungi hal yang salah:
- Interal komponen: Bentuk negara, metode privat, dan props hanya untuk implementasi
- Mechanisme framework: Apakah React telah memperbarui hook secara spesifik seperti yang Anda harapkan secara internal
- Detail anak: Markup yang dimiliki oleh komponen yang terikat yang tidak Anda maksud untuk memverifikasi di sini
Aturan praktis: Jika Anda dapat memperbarui komponen tanpa mengubah apa yang dilihat atau dilakukan oleh pengguna, maka tes tidak perlu berubah juga
Tes unit juga berada di dalam sistem tes yang lebih luas. Mereka tidak mencoba untuk membuktikan bahwa aplikasi seluruhnya berfungsi dari awal hingga akhir. Mereka adalah layer yang cepat yang menangkap regresi sebelum Anda memerlukan tes browser-level atau validasi perangkat-level. Itulah mengapa mereka adalah garis pertama pertahanan dalam setiap stack tes otomatis untuk aplikasi produksi Untuk tim React yang sering mengirimkan aplikasi, kepercayaan datang dari pembagian kerja ini. Tes unit menangkap regresi lokal dengan cepat. Tes integrasi memverifikasi sambungan. Tes akhir-ke-akhir memastikan jalur kritis. Lebihkan layer unit, dan segala sesuatu yang lebih lambat di bawahnya harus membawa beban yang terlalu berat.
Mengatur Lingkungan Tes React Modern
Lingkungan tes yang rapuh menciptakan tes yang flaky sebelum Anda menulis asseri tunggal. Banyak pengembang menyalahkan Jest, jsdom, atau React ketika masalah yang sebenarnya adalah konfigurasi yang tidak konsisten di antara mesin lokal dan CI. Solusinya adalah membuat lingkungan menjadi membosankan. Membosankan adalah baik di sini
Mulai dengan runner dan lingkungan yang dapat diprediksi

Mulai dengan runner dan lingkungan yang dapat diprediksi
Aplikasi React modern, terutama yang dibuat dengan Vite, harus memiliki konfigurasi dasar yang mencakup:
- Sebuah penggunaan tes: Jest masih umum, terutama dalam kodebase React yang lebih tua dan stack CI perusahaan.
- Sebuah lingkungan seperti browser:
jsdombiarkan tes komponen menampilkan output DOM. - Utilitas Testing Library:
@testing-library/reactdan@testing-library/jest-dom - Sebuah entri pintu masuk konfigurasi tunggal: Satu file untuk mendaftarkan matcher dan mock global
Alur kerja yang dipertegas oleh panduan tes React adalah sederhana: render komponen dalam lingkungan jsdom, lakukan query UI dengan selektor seperti getByText atau getByRoleatau Documentasi pengujian ReactNamun, alur kerja tersebut hanya dapat dipercaya jika setiap mesin menjalankan lingkungan pengujian yang sama.
Konfigurasi Jest yang praktis biasanya terlihat seperti ini:
// jest.config.js
module.exports = {
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/src/setupTests.js'],
moduleNameMapper: {
'\\.(css|less|scss)$': 'identity-obj-proxy',
'^@/(.*)$': '<rootDir>/src/$1',
},
transform: {
'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
},
};
Jika tim Anda menggunakan SWC daripada Babel, itu tidak masalah. Poinnya bukan transformer. Poinnya konsistensi. Pilih satu jalur dan standarisasikan di repositori. Jika Anda ingin referensi rekanan yang baik untuk konvensi pengujian JavaScript yang lebih luas, panduan pengujian unit Capgo panduan pengujian unit JavaScript adalah dokumen pengalihan tim yang berguna.
Tambahkan file pengaturan yang akan digunakan oleh suite Anda
Konfigurasi yang tepat setupTests.js menghemat banyak kebisingan yang diulang:
import '@testing-library/jest-dom';
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
File ini adalah tempat Anda menyelesaikan kesenjangan lingkungan sekali saja daripada di dalam dua puluh file pengujian. Tambahkan mock untuk API yang digunakan oleh UI Anda, seperti matchMedia, ResizeObserveratau IntersectionObserverjika library komponen Anda mengharapkannya.
Tanpa hal ini, pengembang akan memperbaiki global secara ad hoc. Hal ini menciptakan tes yang tidak konsisten dan gagal yang sulit untuk diikuti. Salah satu orang’s run lokal berhasil karena mereka menambahkan mock manual dalam sebuah file. CI gagal karena pengaturan tidak dibagikan.
Tetapkan perilaku lokal dan CI sejalan
Perintah lokal harus sesuai dengan perintah CI sejauh mungkin. Jika pengembang menjalankan mode watch dengan pengaturan yang lebih longgar tetapi CI menjalankan konfigurasi yang lebih ketat, Anda akan mendapatkan gagal yang tidak terduga setelah merge. Tetapkan skrip secara eksplisit:
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:ci": "jest --runInBand --coverage"
}
}
Langkah-langkah singkat membantu anggota tim baru mendapatkan basis yang sama dengan cepat:
Pilihan pengaturan yang paling berdampak adalah disiplin seputar pengaturan default. Masukkan alias ke dalam konfigurasi. Masukkan mock lingkungan ke dalam satu file pengaturan. Gunakan jsdom untuk tes UI dan lingkungan yang lebih ringan untuk utilitas murni ketika memungkinkan. Semakin sedikit perilaku yang unik yang setiap tes perlu, semakin andal sistem Anda.
Membuat Tes Komponen yang Bermakna
Organisasi tidak memiliki masalah menulis tes. Mereka memiliki masalah menulis tes yang masih berarti enam bulan kemudian.
Polosan standar untuk menguji komponen React masih benar: render komponen, tanyakan UI dengan selektor yang berpusat pada pengguna, trigger interaksi, dan asertikan perubahan DOM yang dihasilkanyang menjaga tes jauh dari detail implementasi seperti state atau props, seperti yang dijelaskan dalam Petunjuk Pengujian ReactTriknya adalah mengaplikasikan pola tersebut dengan bijak.
Uji accordion seperti pengguna menggunakan aplikasinya.
Ambil komponen dasar. Accordion Komponen ini menampilkan tombol dengan judul. Isi panel dimulai disembunyikan. Klik tombol menampilkan isi dan memperbarui status aksesibilitas.
Itu sudah cukup perilaku untuk beberapa tes yang berguna:
- Render awal menampilkan judul tetapi tidak menampilkan isi.
- Klik tombol trigger menampilkan isi.
- Klik lagi menyembunyikannya.
- Attribut aksesibilitas mencerminkan status yang terlihat.
Poin terakhir seringkali dilupakan. Jika komponen Anda menggunakan , atau struktur berdasarkan peran, verifikasi mereka. Mereka bukanlah detail implementasi. Mereka adalah bagian dari kontrak yang dihadapi pengguna. aria-expanded, aria-controlsTes komponen terbaik membaca seperti laporan bug yang tidak pernah Anda inginkan.
The trick is applying that pattern with restraint.
Pilih kueri berdasarkan niat
React Testing Library memberikan Anda beberapa gaya kueri, tetapi mereka tidak dapat diganti-gantikan. Memilih salah satu yang salah membuat tes menjadi berisik atau menipu.
| Gaya Kueri | Ketika Element Ditemukan | Ketika Element Tidak Ditemukan | Contoh Penggunaan |
|---|---|---|---|
getBy |
Mengembalikan elemen segera | Mengembalikan kesalahan segera | Pastikan tombol atau judul sudah ada di layar |
queryBy |
Mengembalikan elemen segera | Mengembalikan null |
Mengembalikan elemen segera |
findBy |
Menyelesaikan ketika elemen muncul | Mengakui setelah menunggu | Menegaskan konten yang dimuat secara async muncul setelah fetch atau pembaruan yang tertunda |
Model mental sederhana membantu:
- Pakai
getByuntuk hal-hal yang harus sudah ada. - Pakai
queryByuntuk hal-hal yang harus belum ada. - Pakai
findByketika UI berubah kemudian.
Jika sebuah tes dimulai dengan findBy Pakai untuk semua, biasanya berarti penulis tidak yakin kapan komponen diperbarui. Ketidakpastian ini menjadi fluktuasi kemudian.
Aplikasi accordion yang berguna
Contoh komponen yang mewakili:
function Accordion({ title, children }) {
const [open, setOpen] = React.useState(false);
return (
<section>
<button
aria-expanded={open}
aria-controls="accordion-panel"
onClick={() => setOpen(prev => !prev)}
>
{title}
</button>
{open ? (
<div id="accordion-panel">
{children}
</div>
) : null}
</section>
);
}
Dan bentuk tes yang layak disimpan:
import { render, screen, fireEvent } from '@testing-library/react';
test('renders the accordion title and hides content initially', () => {
render(<Accordion title="Shipping details">Delivery takes 3 days</Accordion>);
expect(screen.getByRole('button', { name: /shipping details/i })).toBeInTheDocument();
expect(screen.queryByText(/delivery takes 3 days/i)).not.toBeInTheDocument();
});
test('reveals content when the trigger is clicked', () => {
render(<Accordion title="Shipping details">Delivery takes 3 days</Accordion>);
fireEvent.click(screen.getByRole('button', { name: /shipping details/i }));
expect(screen.getByText(/delivery takes 3 days/i)).toBeInTheDocument();
});
test('updates aria-expanded when opened', () => {
render(<Accordion title="Shipping details">Delivery takes 3 days</Accordion>);
const button = screen.getByRole('button', { name: /shipping details/i });
expect(button).toHaveAttribute('aria-expanded', 'false');
fireEvent.click(button);
expect(button).toHaveAttribute('aria-expanded', 'true');
});
Yang hilang pun sangat penting. Tidak ada asseri terhadap keadaan internal. Tidak ada pengecekan bahwa setOpen telah dipanggil. Tidak ada snapshot dari pohon yang di-render secara keseluruhan. Tes-tes tersebut akan menambahkan perawatan, bukan kepercayaan.
Beberapa kebiasaan membuat tes komponen lebih kuat:
- Menggunakan kueri berdasarkan peran: Botton, judul, dialog, peringatan, dan input biasanya harus ditemukan berdasarkan peran.
- Membuat setiap tes lebih sempit: Satu perilaku yang dapat dilihat pengguna per tes membuat kegagalan lebih mudah dibaca.
- Mengasihkan nama tes setelah hasil: “Mengupdate aria-expanded ketika dibuka” sangat lebih berguna daripada “berfungsi dengan benar.”
Jika sebuah komponen sulit diuji melalui DOM, hal itu sering kali menunjukkan masalah desain. Mungkin komponen menyembunyikan keadaan di tempat yang salah. Mungkin komponen kurang memiliki markup semantik. Tes yang baik sering kali mendorong tim ke arah komponen yang lebih baik.
Tes Hook Kustom dan Logika Aplikasi
Aplikasi React menyembunyikan banyak perilaku penting di luar komponen. Transisi keadaan hidup di hook. Validasi dan pengaturan format hidup di fungsi bantuan. Pengubahan data sering kali terjadi sebelum apa pun menampilkan. Jika Anda hanya menguji komponen yang terlihat, Anda akan melewatkan sebagian besar code yang masih dapat memecahkan perilaku produksi.
Hook memerlukan harness yang menyadari React
Hook kustom masih memerlukan React untuk berjalan dengan benar, jadi uji dengan renderHook dan tutup panggilan yang mengubah keadaan dengan act().
Contoh kecil useToggle Hook adalah contoh yang baik:
import { useState, useCallback } from 'react';
export function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);
const toggle = useCallback(() => setValue(current => !current), []);
return { value, toggle };
}
Tesnya harus tetap fokus pada kontrak publik:
import { renderHook, act } from '@testing-library/react';
import { useToggle } from './useToggle';
test('returns the initial value', () => {
const { result } = renderHook(() => useToggle(true));
expect(result.current.value).toBe(true);
});
test('toggles the value', () => {
const { result } = renderHook(() => useToggle(false));
act(() => {
result.current.toggle();
});
expect(result.current.value).toBe(true);
});
Tes ini berguna karena hook itu sendiri adalah unit. Anda tidak menguji internal React. Anda memverifikasi perilaku eksternal hook.
Untuk tim produk yang membangun UI atau primitif fitur yang dapat digunakan kembali, pola ini sangat penting. Hook sering kali menjadi interface yang dibagikan di antara aplikasi, sistem desain, atau alat internal. Jika Anda merancang perilaku yang dapat digunakan kembali dengan niat komersial, sumber daya pada hook untuk produk pembuat bisa membantu menggambarkan hook sebagai blok bangunan yang dihasilkan daripada hanya detail implementasi.
Logika murni harus tetap murni dalam tes.
Segala sesuatu tidak perlu jsdom, React, atau Testing Library. Jika sebuah fungsi bersih, tesnya dengan menggunakan Jest biasa di lingkungan Node.
Contoh:
export function formatDisplayName(firstName: string, lastName: string) {
return `${firstName.trim()} ${lastName.trim()}`.trim();
}
Tes tersebut harus sangat sederhana:
import { formatDisplayName } from './formatDisplayName';
test('joins and trims both names', () => {
expect(formatDisplayName(' Ada ', ' Lovelace ')).toBe('Ada Lovelace');
});
test('handles a missing last name', () => {
expect(formatDisplayName('Ada', '')).toBe('Ada');
});
Kemenangan di sini adalah kecepatan dan kejelasan. Ketika sebuah fungsi tidak memerlukan pohon render, jangan berikan padanya. Alat-alat khusus React menambahkan beban. Tes logika bisnis harus kecil, cepat, dan dekat dengan fungsi yang mereka verifikasi.
Penyebutan yang praktis bekerja dengan baik:
- Hooks: Pakai
renderHook,act(), dan penyedia wrapper ketika diperlukan. - Utilitas: Gunakan Jest biasa dan tidak DOM.
- Logika lintas potongan yang berubah-ubah: Pakailah bantuan yang dapat diuji ketika tes komponen mulai melakukan terlalu banyak logika.
Tim seringkali melebih-lebihkan tes komponen dengan asertasi logika yang seharusnya lebih rendah di stack. Mengeluarkan logika itu memberikan dua manfaat. Tes komponen menjadi lebih bersih, dan tes logika menjadi lebih cepat.
Menguasai Teknik-teknik Lanjutan Mocking dan Synchronous
Banyak suite React yang tidak dapat diandalkan rusak di dua tempat. Mereka rusak di batasan ketergantungan, dan mereka rusak di sekitar waktu.
Itu mengapa tes asinkron dan mocking adalah garis pembagi antara suite tes mainan dan satu yang dapat dipercaya sebelum rilis. Satu analisis mengatributkan 46,5% dari ketidakstabilan tes ke masalah lingkungan atau terkait sumber daya seperti waktu asinkron di analisis tes React ini. Di aplikasi React, itu langsung berhubungan dengan transisi keadaan, rendering yang tertunda, UI yang dikemudikan oleh jaringan, dan tes yang menebak alih-alih menunggu secara deterministik.

Jangan mock lapisan, tapi batasnya
Metode tercepat untuk menulis tes yang menipu adalah dengan mengmock setengah pohon komponen dan kemudian mengklaim bahwa mock sendiri berhasil.
Untuk komponen yang mengambil data akun, mock klien jaringan atau modul API. Jangan mock hook, komponen anak baris, spinner loading, dan tiga fungsi utilitas kecuali tes benar-benar memerlukan isolasi di titik-titik tersebut.
Gunakan set aturan ini:
- Mock layanan eksternal: Klien HTTP, analitik, API browser-only, jembatan native
- Mock API platform tidak stabil:
matchMediatimer, interface preload Electron, plugin Capacitor ketika tidak tersedia di jsdom - Hindari mock internal sendiri secara default: hook kustom, anak sederhana, utilitas lokal
Jika tes melewati karena semua bagian yang sulit digantikan dengan palsu, maka tidak ada kepercayaan yang diperoleh.
Untuk tim yang ingin contoh dan pola seputar API runner, Capgo tutorial tes adalah sebuah referensi perpustakaan yang sangat berguna, terutama ketika mengontrak pengembang yang sudah tahu React tapi belum mengerti mekanisme tes.
Tes asinkron gagal ketika waktu tidak jelas
Gagal asinkron biasanya berasal dari salah satu dari tiga kesalahan:
- Tes mengklaim terlalu cepat.
- Tes menunggu dengan pengatur waktu acak.
- Komponen diperbarui lebih dari sekali, tapi tes hanya menggambarkan satu transisi.
Tes asinkron stabil biasanya memiliki bentuk seperti ini:
test('shows user details after data loads', async () => {
render(<UserProfile userId="42" />);
expect(screen.getByText(/loading/i)).toBeInTheDocument();
expect(await screen.findByText(/account owner/i)).toBeInTheDocument();
});
Atau, ketika Anda perlu menunggu kondisi tertentu:
await waitFor(() => {
expect(screen.getByRole('alert')).toBeInTheDocument();
});
Pilih findBy ketika penampilan satu elemen adalah acara yang Anda pedulikan. Pilih waitFor ketika kondisi lebih luas atau keadaan tidak bisa diungkapkan dengan satu query. Hindari setTimeout kecuali Anda secara eksplisit menguji perilaku timer dan menggunakan timer palsu.
Ekosistem pengujian React juga mengharapkan Anda untuk menghormati act() semantik seputar pembaruan. Library Pengujian menangani banyak hal ini untuk Anda, tetapi jika Anda mengemudi keadaan secara manual atau maju timer, Anda masih perlu berpikir tentang kapan pembaruan mengalir.
Tahu alat mocking mana yang harus digunakan
Alat mocking yang berbeda-beda menyelesaikan masalah yang berbeda:
| Alat | Penggunaan terbaik | Kesalahan umum |
|---|---|---|
jest.fn() |
Panggilan balik palsu yang berdiri sendiri atau fungsi yang diinjeksikan | Menggunakan alat ini untuk menggantikan modul seluruhnya ketika panggilan balik sederhana sudah cukup |
jest.spyOn() |
Melihat atau mengubah satu metode pada objek atau modul yang nyata | Mengabaikan untuk memulihkan implementasi asli |
jest.mock() |
Ubah dependensi modul di batas import | Menggunakan metode mock untuk modul besar secara default dan kehilangan perilaku yang bermakna |
Contoh bantuan:
- Cari
jest.fn()ketika komponen menerimaonSubmitprop. - Pakai
jest.spyOn()ketika Anda perlu memastikanconsole.errorsuatu metode penyimpanan, atau satu panggilan API yang diekspor. - Pakai
jest.mock()ketika mengimport modul akan mengakibatkan akses I/O, native code, atau perilaku di luar batas unit.
Salah satu area yang maju yang banyak panduan tidak menyediakan adalah pengujian jalur kesalahan di React modern. Batasan kesalahan, perubahan keadaan yang tertunda, dan UI fallback async patut mendapatkan pengujian kelas pertama, bukan hanya contoh klik "happy path". Jika anaknya melempar, asertkan UI fallback yang terlihat. Jika permintaan gagal, asertkan keadaan pemulihan yang terlihat. Jika tombol dinonaktifkan selama penggunaan, asertkan juga itu. Itulah bug yang pengguna ingat.
{
Meningkatkan Kualitas dan Strategi Pengujian
Mengapa Banyak Tim Masih Mengikuti Indeks Pengujian Seperti Halnya dengan Kepercayaan.

Anda dapat mencapai target pengujian dan masih melewatkan regresi yang penting.
Satu suite penuh asseri dangkal, snapshot luas, dan internal yang dimock dapat menciptakan kesan keamanan sementara meningkatkan biaya perawatan.
Infografis yang membandingkan manfaat pengujian kualitas dengan biaya perawatan yang tinggi dari suite pengujian kuantitas tinggi.
Pengujian adalah Peta, bukan Tujuan.
- Laporan pengujian dapat berguna ketika menjawab satu pertanyaan: jalur kritis mana yang belum dilindungi? Mereka tidak berguna ketika mendorong pengembang untuk menguji wrapper yang tidak penting, markup statis, atau file yang dapat melewati dengan satu baris kode hanya untuk meningkatkan persentase.
- Tangani pengujian sebagai alat penemuan. Jika keadaan autentikasi, aksi tagihan, flag fitur, atau prompt pembaruan tidak memiliki pengujian, itu adalah tanda. Jika komponen ikon presentasional tidak memiliki pengujian, biasanya bukanlah hal yang penting.
- No: It mengklaim detail implementasi atau mengulangi nilai tes lain.
Apa yang tidak perlu diuji unit
Banyak panduan React masih tidak menghabiskan waktu yang cukup untuk pengabaian. Gap ini penting karena over-mocking dan pengujian detail implementasi menciptakan suite yang rapuh yang dapat melewati tes, tetapi pengalaman pengguna masih rusak, seperti yang disebutkan dalam panduan BrowserStack tentang apa yang tidak perlu diuji unit di React.
Lepaskan atau sangat limitkan pola-pola berikut:
- Pengakuan keadaan internal: Jangan menguji
isOpenlangsung ketika Anda dapat menguji apakah panel terbuka. - Penggunaan framework: Jangan menguji bahwa React telah memanggil efek. Uji hasil dari apa yang efek mengubah.
- Interal perpustakaan pihak ketiga: Uji integrasi Anda dengan tanggal pilih atau router, bukan logika rendering sendiri dari library.
- Unit-unit yang terlalu banyak rusak: Jika Anda telah memalsukan setiap anak dan bantuan, maka Anda mungkin tidak lagi menguji perilaku yang bermakna.
Tes yang buruk lebih buruk daripada tes yang hilang ketika mereka menghalangi refaktor dan masih gagal menangkap bug produksi.
Heuristik yang berguna adalah kepemilikan batas. Uji apa yang code Anda miliki. Jangan uji apa yang React, browser, atau library yang matang sudah miliki kecuali layer integrasi Anda mengubah kontrak.
Dimana snapshot membantu dan dimana mereka menyakiti:
Snapshot tidaklah sia-sia. Mereka hanya mudah digunakan secara tidak tepat.
Pakai mereka dengan sedikit untuk komponen dengan output yang stabil dan sederhana di mana perbedaan struktur yang luas bermakna. Hindari mereka untuk komponen interaktif atau dinamis karena mereka menjadi kebisingan. Pengembang berhenti membaca mereka dan mulai memperbarui mereka secara refleksif.
Alternatif yang lebih baik biasanya ada:
- Untuk rendering kondisional, asertkan kehadiran atau ketiadaan teks kunci.
- Untuk perubahan visual, asertkan peran, label, atau atribut yang penting.
- Untuk kesalahan dan fallback, asertkan pesan yang sebenarnya atau wilayah peringatan.
Jika tim Anda membutuhkan proses kualitas yang lebih luas di luar unit test, teman yang solid adalah alur jaminan kualitas aplikasi yang menganggap tes, periksa rilis, dan perencanaan rollback sebagai satu sistem. Perubahan mindset yang mempercepat kualitas tes tercepat. Berhenti bertanya berapa banyak tes Anda. Mulai bertanya mana saja kegagalan yang masih bisa mencapai pengguna.
Integrasi Tes ke Pipa CI/CD Berbasis Multi-Platform
Suatu suite tes yang hanya berjalan di laptop pengembang adalah saran, bukan kontrol.
Suite menjadi operasional ketika setiap permintaan pull berjalan pada periksaan yang sama di lingkungan bersih dan menghalangi merge ketika periksaan gagal. Ini terdengar jelas, tapi banyak tim masih meninggalkan celah-celah kritis. Tes berjalan secara manual. Laporan coverase adalah opsional. Tugas pengemasan dan rilis dimulai sebelum tugas tes selesai. Itulah cara kecil bug UI masuk ke kegagalan rilis yang lebih besar.

Permintaan pull harus mengaktifkan pintu gerbang yang sama setiap kali
Untuk melakukan unit testing React seperti jaringan keselamatan, CI membutuhkan beberapa hal penting:
- Jalankan pada setiap permintaan pull
- Instal dependensi dari file lock
- Pakai perintah tes yang sama setiap kali
- Berhenti cepat pada gagalnya tes
- Publikasikan artefak hanya setelah tes berhasil
Ini adalah inti dari praktik pengiriman terus-menerus untuk tim aplikasi. Bangun kepercayaan sebelum rilis, bukan setelah.
Aktifitas sederhana GitHub Workflow cukup untuk banyak tim:
name: test
on:
pull_request:
push:
branches:
- main
jobs:
react-tests:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm run test:ci
Ini tidak rumit, dan itu poinnya. Pipa yang kuat biasanya adalah yang paling tidak mengejutkan.
Mengapa hal ini lebih penting untuk Capacitor dan Electron
Aplikasi React yang berplatform multi berisiko rilis lebih besar daripada aplikasi browser-only karena UI code seringkali berbeda dalam kontainer yang berbeda dengan asumsi runtime yang berbeda.
Beberapa contoh menunjukkan bagaimana pipa membantu:
- Aplikasi Capacitor: Aplikasi web code mungkin berhasil secara lokal tetapi gagal ketika jembatan plugin, keadaan offline, atau kasus edge aplikasi siklus kehidupan mengubah perilaku setelah pengemasan.
- Applikasi Electron: A komponen renderer mungkin bergantung pada API preload, pesan jendela, atau keadaan desktop yang tidak akan ada dalam pengujian browser biasa kecuali dengan sengaja di mock.
- Relasi rilis bersama: Satu bundle buruk dapat mempengaruhi target-target lain jika proses pengiriman Anda tidak mengunci publikasi dengan ketat.
Itulah mengapa tes unit harus dijalankan sebelum pekerjaan pengemasan, dan pekerjaan pengemasan harus dijalankan sebelum pekerjaan distribusi. Setiap tahap mempersempit risiko. Tes unit menangkap kembali regresi lokal dengan cepat. Pengemasan platform memverifikasi asumsi lingkungan. Persetujuan manual atau peluncuran berjenjang menangani kepercayaan rilis akhir.
Alur kerja praktis GitHub
Alur kerja yang lebih dewasa biasanya membagi tanggung jawab:
- Pekerjaan tes: Tes unit dan hook yang cepat
- Pekerjaan pembangunan: Pembangunan produksi hanya setelah tes berhasil
- Pekerjaan pengemasan: Capacitor sinkronisasi, pengemasan Electron, atau penggabungan artefak
- Job Rilis: Hanya publikasikan dari cabang atau tag yang disetujui
Untuk tim yang mengirimkan pembaruan hidup ke Capacitor atau aplikasi Electron, hal ini adalah tempat alat rilis berperan. Salah satu pilihan dalam alur kerja tersebut adalah Capgo, yang menerbitkan paket web yang ditandatangani untuk aplikasi CapacitorJS dan Electron dengan dukungan rollback dan kontrol rollout berdasarkan saluran. Dalam prakteknya, itu berarti pekerjaan tes React Anda dapat berfungsi sebagai pintu keras pertama sebelum paket web apa pun dipromosikan ke pengiriman staging atau produksi.
Aturan operasionalnya sederhana. Jangan biarkan infrastruktur rilis menggantikan tes yang lemah. Gunakan infrastruktur rilis setelah tes yang dapat diandalkan telah menyaring perubahan yang buruk.
Sistem tes yang dapat diandalkan mengubah perilaku tim. Para insinyur bergabung dengan lebih sedikit kebingungan. Para pemeriksa fokus pada kasus sampingan daripada menjalankan dasar secara manual. Manajer rilis berhenti menganggap setiap deploy seperti taruhan. Itulah hasil dari melakukan unit testing React dengan baik.
Jika tim Anda mengirimkan React melalui Capacitor atau Electron, keamanan rilis bergantung pada lebih dari tes lokal hijau. Capgo memberikan tim cara yang dikendalikan untuk menerbitkan pembaruan web yang ditandatangani, menargetkan saluran rollout, dan mengembalikan paket yang buruk tanpa menunggu ulasan toko, yang sesuai dengan alami di belakang pipeline CI yang sudah memerlukan melewati tes unit sebelum pengiriman.