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. Build mobile berperilaku berbeda setelah perubahan status asinkron. Tidak ada yang menangkapnya karena code memiliki tes, tapi tidak tes yang tepat, dan pasti tidak sistem yang dapat diandalkan sekitar tes itu.
Masalah utama dengan unit testing React di tim produksi adalah menulis beberapa tes yang berhasil bukanlah hal sulit. Namun, membangun suatu suite yang masih melindungi Anda selama refactor, kereta rilis, hotfix, dan pengemasan lintas-platform adalah bagian yang sulit. Aplikasi React gagal karena tim lupa cara memanggil render(). Mereka gagal karena tes mengarah ke detail implementasi, perilaku asinkron disembunyikan, dan CI menganggap tes sebagai kotak centang daripada pintu rilis.
Pengujian unit modern React berfungsi ketika berperilaku seperti sistem keamanan. Feedback cepat lokal. Periksa yang terprediksi di CI. Batasan yang jelas di sekitar apa yang termasuk dalam pengujian unit dan apa yang tidak. Hal ini lebih penting lagi ketika kode React yang sama dikirim melalui browser, Capacitor kontainer, atau shell Electron.
Isi Kandungan
- Mengapa Unit Testing React Adalah Jaringan Keamanan Terbaik Anda
- Menyiapkan Lingkungan Pengujian React Modern Anda
- Menggunakan Pengujian Komponen yang Bermakna
- Menguji Hook-Hook Kustom dan Logika Aplikasi
- Menguasai Teknik-Teknik Lanjutan Mocking dan Async
- Meningkatkan Kualitas dan Strategi Pengujian
- Mengintegrasikan Tes ke Pipa CI/CD Cross-Platform
Mengapa Pengujian Satuan React adalah Jaringan Keamanan Terbaik Anda
Unit test memperoleh kegunaannya ketika mereka menangkap kesalahan yang Anda percayai tidak akan terjadi. Di React, biasanya berarti komponen masih menampilkan, tetapi perilaku yang digunakan oleh pengguna telah berubah. Tombol yang dinonaktifkan menjadi dapat diklik. Status loading tidak pernah hilang. Pesan pengganti hilang setelah refactor. Kerugian-kerugian kecil itu di code dan mahal di produksi.
Reaksi pengujian berubah dalam cara yang penting ketika Pengujian React Library menjadi model utama untuk menguji perilaku bukanlah bagian internal, mendorong tim menuju pengujian yang mengacu pada perilaku pengguna bukanlah atribut komponen atau keadaan, seperti yang tercermin dalam panduan pengujian React Native di Panduan pengujian React Native. Perubahan itu penting karena React code selalu berubah. Hooks berpindah. Komponen terpecah. Konteks diperkenalkan. Pengujian yang terkait dengan struktur internal rusak selama refactor yang sehat. Pengujian yang terkait dengan perilaku yang dapat dilihat biasanya bertahan.
Apa yang harus dilindungi oleh unit test
Pengujian unit React yang baik melindungi satu kontrak kecil:
- Output yang ditampilkan: Apakah pengguna melihat teks, label, keadaan, atau fallback yang benar?
- Perilaku interaksi: Apakah klik, tipe, atau toggle mengubah UI dengan benar?
- Penanganan batas: Apakah komponen berperilaku dengan benar ketika menerima input yang diharapkan, data yang hilang, atau jalur kesalahan?
Tes yang lemah melindungi hal yang salah:
- Rincian komponen internal: Bentuk negara, metode pribadi, dan properti implementasi saja
- Mechanika framework: Apakah React telah memperbarui hook dengan cara yang tepat seperti yang Anda harapkan secara internal?
- Detail anak: Markup yang dimiliki oleh komponen anak yang tidak Anda maksud untuk memverifikasi di sini
Aturan praktis: Jika Anda dapat merubah komponen tanpa mengubah apa yang dilihat atau dilakukan oleh pengguna, maka tes tidak perlu berubah juga.
Tes unit juga berada di dalam sistem pengujian yang lebih luas. Mereka tidak mencoba untuk membuktikan bahwa aplikasi berjalan secara keseluruhan dari awal hingga akhir. Mereka adalah lapisan 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 yang masuk akal pengujian otomatis untuk aplikasi produksi.
For tim React yang sering mengirimkan, kepercayaan datang dari pembagian kerja ini. Uji unit menangkap regresi lokal dengan cepat. Uji integrasi memverifikasi sambungan. Uji akhir-ke-akhir memastikan jalur kritis. Lebih baik melewatkan layer unit, dan segala yang lebih lambat di bawahnya harus membawa terlalu banyak beban.
Pengaturan Lingkungan Pengujian React Modern Anda
Suatu lingkungan pengujian yang rapuh menciptakan tes yang berantakan sebelum Anda menulis asseri tunggal. Banyak pengembang menyalahkan Jest, jsdom, atau React ketika masalah dasar adalah konfigurasi yang tidak konsisten di mesin lokal dan CI. Solusinya adalah membuat lingkungan menjadi membosankan. Membosankan adalah baik di sini.

Mulai dengan runner yang dapat diprediksi dan lingkungan
Untuk aplikasi React modern, terutama yang dibuat dengan Vite, pengaturan dasar harus mencakup:
- Runner pengujian: Jest masih umum, terutama di kodebase React yang lebih tua dan stack CI perusahaan.
- Lingkungan seperti browser:
jsdombiarkan tes komponen menampilkan output DOM. - Fasilitas utilitas Library Pengujian:
@testing-library/reactdan@testing-library/jest-dom - A Single Entry Point: Satu File untuk Mendaftarkan Matcher dan Mock Global
Alur kerja utama yang panduan pengujian React kuatkan adalah sederhana: render komponen di lingkungan jsdom, lakukan query UI dengan selektor seperti getByText atau getByRole, trigger interaction, and assert the DOM change, as described in the Dokumentasi Pengujian ReactJika alur kerja itu hanya dapat dipercaya jika setiap mesin menjalankan lingkungan uji yang sama.
Pengaturan 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',
},
};
If your team uses SWC instead of Babel, that’s fine. The point isn’t the transformer. The point is consistency. Choose one path and standardize it in the repo. If you want a good companion reference for broader JavaScript testing conventions, Capgo’s Panduan Pengujian Satuan JavaScript Dokumen transfer tim yang berguna.
Tambahkan file pengaturan yang akan digunakan oleh suite Anda
A 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 bukan di dalam dua puluh file tes. Tambahkan mock untuk API yang UI Anda bergantung pada, seperti matchMedia, ResizeObserver, atau IntersectionObserver, jika library komponen Anda mengharapkannya.
Tidak ada ini, pengembang akan memperbaiki global secara ad hoc. Hal ini menciptakan tes yang tidak konsisten dan kesalahan yang sulit untuk diikuti. Salah satu orang’s run lokal berhasil karena mereka menambahkan mock manual di file. CI gagal karena pengaturan tidak dibagikan.
Tetapkan perilaku lokal dan CI sejalan
Perintah lokal harus sejalan dengan perintah CI sejauh mungkin. Jika pengembang menjalankan mode watch dengan default yang lebih longgar tetapi CI menjalankan konfigurasi yang lebih ketat, Anda akan mendapatkan kegagalan yang tidak terduga setelah merge. Tetapkan skrip 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 default. Masukkan alias di konfigurasi. Masukkan mock lingkungan di 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 individu memerlukan, semakin andal sistem Anda menjadi.
Menulis Uji Coba Komponen yang Bermakna
Perusahaan tidak memiliki masalah menulis uji coba. Mereka memiliki masalah menulis uji coba yang masih berarti enam bulan kemudian.
Polosan standar untuk menguji komponen React secara unit masih polosan yang tepat: Mengrender komponen, mengakses UI dengan selektor yang berfokus pada pengguna, memicu interaksi, dan mengasumsikan perubahan DOM yang dihasilkan.yang menjaga tes jauh dari detail implementasi seperti state atau props, seperti yang dijelaskan dalam Petunjuk Pengujian ReactUji coba accordion seperti pengguna menggunakannya
Tes accordion seperti pengguna yang menggunakan aplikasi
Coba unit testing dasar Accordion Komponen ini menampilkan tombol dengan judul. Isi panel awalnya disembunyikan. Ketika tombol diklik, konten akan muncul dan mengupdate status aksesibilitas.
Tampilkan awal menampilkan judul tetapi tidak menampilkan isi.
- Tampilkan awal menampilkan judul tetapi tidak menampilkan isi.
- Mengklik tombol trigger menampilkan konten.
- Mengklik lagi menyembunyikannya.
- Atribut aksesibilitas mencerminkan status yang terlihat.
Poin terakhir seringkali dilupakan. Jika komponen Anda menggunakan aria-expanded, aria-controlsatau struktur berdasarkan peran, pastikan mereka. Mereka bukanlah detail implementasi. Mereka adalah bagian dari kontrak yang menghadap pengguna.
Tes komponen terbaik membaca seperti laporan bug yang tidak pernah Anda inginkan.
Pilih kueri berdasarkan niat.
Perpustakaan Pengujian React memberikan Anda beberapa gaya kueri, tetapi mereka tidak dapat diganti. Memilih salah satu yang salah membuat tes menjadi berisik atau menipu.
| Jenis Pemintaan | Ketika Element Tidak Ditemukan | Ketika Komponen Tidak Ditemukan | Contoh Penggunaan |
|---|---|---|---|
getBy |
Mengembalikan elemen segera | Mengembalikan kesalahan segera | Menegaskan tombol atau judul harus sudah ada di layar |
queryBy |
Mengembalikan elemen segera | Mengembalikan null |
Menegaskan konten disembunyikan tidak ada sebelum interaksi |
findBy |
Terpecahkan ketika elemen muncul | Mengembalikan 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. - Gunakan
queryByuntuk hal-hal yang harus tidak ada sebelumnya. - Gunakan
findByketika tampilan UI berubah nanti.
Jika sebuah tes dimulai dengan findBy untuk segalanya, biasanya berarti penulis tidak yakin kapan komponen diperbarui. Ketidaktentuan tersebut menjadi fluktuasi nanti.
Contoh Accordion yang Praktis
Berikut adalah komponen representatif:
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 berikut adalah bentuk tes yang layak dipertahankan:
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');
});
Apa yang hilang pun sangat penting. Tidak ada asseri terhadap keadaan internal. Tidak ada pengecekan bahwa setOpen dipanggil. Tidak ada snapshot dari pohon yang di-render secara keseluruhan. Tes-tes tersebut akan menambah biaya perawatan, bukan kepercayaan.
Beberapa kebiasaan membuat tes komponen lebih kuat:
- Prefer query berdasarkan peran: Button, judul, dialog, peringatan, dan input biasanya dapat ditemukan melalui peran.
- Jaga setiap tes sempit: Satu perilaku yang dapat dilihat pengguna per tes menjaga gagal baca.
- Nama tes setelah hasil: "“mengupdate aria-expanded ketika dibuka” lebih berguna daripada “berfungsi dengan benar.””
If a component is hard to test through the DOM, that often reveals a design problem. Maybe it hides state in the wrong place. Maybe it lacks semantic markup. Good tests often push teams toward better components.
Menguji Hook-Hook Kustom dan Logika Aplikasi
React apps hide a lot of important behavior outside components. State transitions live in hooks. Validation and formatting live in helper functions. Data shaping often happens before anything renders. If you only test visible components, you’ll miss a large part of the code that can still break production behavior.
Hooks memerlukan sebuah harness yang menyadari React
Aplikasi hook kustom masih memerlukan React untuk berjalan dengan benar, jadi tesnya dengan renderHook dan tutup panggilan yang mengubah state dalam act().
Apa yang 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 itu berguna karena hook itu sendiri adalah unit. Anda tidak sedang menguji internal React. Anda memverifikasi perilaku eksternal hook.
Untuk tim produk yang membangun komponen UI atau primitif fitur yang dapat digunakan kembali, pola ini sangat penting. Hook seringkali menjadi antarmuka yang digunakan bersamaan di antara aplikasi, sistem desain, atau alat bantu internal. Jika Anda merancang perilaku yang dapat digunakan kembali dengan niat komersial, sumber daya tentang hook untuk produk pembuat bisa membantu menggambarkan hook sebagai blok bangunan yang dapat digunakan kembali daripada hanya detail implementasi.
Logika murni harus tetap murni dalam tes
Tidak semua memerlukan jsdom, React, atau Testing Library. Jika fungsi adalah logika murni, tesnya dengan menggunakan Jest biasa di lingkungan Node.
Contoh:
export function formatDisplayName(firstName: string, lastName: string) {
return `${firstName.trim()} ${lastName.trim()}`.trim();
}
Tesnya 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');
});
Keuntungan utama di sini adalah kecepatan dan kejelasan. Ketika sebuah fungsi tidak memerlukan pohon yang di-render, jangan berikan padanya. Alat-alat React menambahkan beban. Pastikan tes logika bisnis kecil, cepat, dan dekat dengan fungsi yang mereka verifikasi.
Penyebaran yang praktis bekerja dengan baik:
- Hook: Pakai
renderHook,act(), dan penyedia wrapper ketika diperlukan. - Utilitas: Pakai Jest biasa dan tidak DOM.
- Logika yang berubah-ubah: Tarik ke dalam bantuan yang dapat diuji ketika tes komponen mulai melakukan terlalu banyak.
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.
Penguasaan Teknik-teknik Lanjutan Mocking dan Async
Banyak suite React yang tidak dapat diandalkan rusak di dua tempat. Mereka rusak di batasan ketergantungan, dan mereka rusak di sekitar waktu.
Alasan itu, pengujian asinkron dan pemalsuan adalah garis pemisah antara suatu suite pengujian mainan dan satu yang dapat dipercaya sebelum rilis. Satu analisis atributkan 46,5% dari ketidakstabilan pengujian disebabkan oleh masalah lingkungan atau terkait sumber daya seperti pengaturan waktu asinkron in analisis pengujian unit React iniDalam aplikasi React, itu berarti transisi keadaan, rendering yang tertunda, antarmuka pengguna yang dikendalikan oleh jaringan, dan tes yang menebak alih-alih menunggu secara deterministik.

Palsukan batas, bukan setiap lapisan
Cara termudah untuk menulis tes yang menipu adalah dengan memalsukan setengah pohon komponen dan kemudian mengklaim bahwa palsuan Anda sendiri berhasil.
Untuk komponen yang mengambil data akun, palsukan klien jaringan atau API modul. Jangan palsukan hook, komponen baris anak, spinner loading, dan tiga fungsi utilitas kecuali tes benar-benar memerlukan isolasi di tempat-tempat tersebut.
Gunakan set aturan ini:
- Palsukan layanan eksternal: Klien HTTP, analitik, API browser-only, jembatan native
- Mock API platform yang tidak stabil:
matchMedia, timer, interface Electron preload, plugin Capacitor ketika tidak tersedia di jsdom - Menghindari mock internal Anda sendiri secara default: hook kustom, anak-anak sederhana, utilitas lokal
Jika tes melewati karena semua bagian yang sulit digantikan dengan palsu, maka itu tidak memberikan Anda banyak kepercayaan diri untuk merilis.
Untuk tim yang ingin contoh dan pola seputar API runner, Capgo tutorial tes adalah sebuah referensi library yang praktis, terutama ketika mengontrak pengembang yang tahu React tapi belum tahu mekanisme tes.
Tes asinkron gagal ketika waktu tidak jelas
Kegagalan asinkron biasanya berasal dari salah satu dari tiga kesalahan:
- Tes mengklaim terlalu cepat.
- Tes menunggu dengan timer yang acak.
- Komponen ini diperbarui lebih dari sekali, tetapi tes hanya menggambarkan satu transisi.
Aplikasi tes async stabil biasanya memiliki bentuk:
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();
});
Pakai findBy ketika penampilan satu elemen adalah acara yang kamu pedulikan. Gunakan waitFor ketika kondisi lebih luas atau keadaan tidak dapat diungkapkan dengan satu query. Hindari setTimeout ketika kondisi lebih luas atau keadaan tidak dapat diungkapkan dengan satu query. Hindari
Sistem pengujian React juga mengharapkan Anda untuk menghormati act() semantics around updates. Testing Library handles a lot of this for you, but if you’re driving state manually or advancing timers, you still need to think about when updates flush.
Tahu pilihan alat mock yang tepat
Kenali alat mocking mana yang harus digunakan
| Tool | Best use | Kesalahan umum |
|---|---|---|
jest.fn() |
Panggilan palsu berdiri sendiri atau fungsi yang diinjeksikan | Menggunakan itu untuk menggantikan modul utuh ketika callback sederhana sudah cukup |
jest.spyOn() |
Melihat atau menggantikan satu metode pada objek atau modul nyata | Mengabaikan untuk memulihkan implementasi asli |
jest.mock() |
Menggantikan ketergantungan modul pada batas import | Menggunakan palsu secara default untuk modul besar dan kehilangan perilaku yang bermakna |
Contoh membantu:
- Cari untuk
jest.fn()ketika komponen menerimaonSubmitprop. - Gunakan
jest.spyOn()ketika Anda perlu memastikanconsole.error, sebuah metode penyimpanan, atau satu API panggilan yang diekspor. - Gunakan
jest.mock()ketika mengimpor sebuah modul akan mengakibatkan 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, asertikan UI fallback. Jika permintaan gagal, asertikan keadaan pemulihan yang terlihat. Jika tombol dinonaktifkan selama pengisian, asertikan juga itu. Itu adalah bug yang pengguna ingat.
Meningkatkan Kualitas dan Strategi Pengujian
Banyak tim masih mengejar koverasi seperti halnya kepercayaan. Tidaklah sama.
Anda bisa mencapai target coverase dan masih melewatkan regresi yang penting. Suatu suite penuh asertasi dangkal, sketsa lebar, dan internal yang dimock membuat penampilan keamanan sementara juga meningkatkan biaya perawatan.

Coverase adalah peta, bukan tujuan
Laporan coverase berguna ketika menjawab satu pertanyaan: jalur kritis mana yang belum dilindungi?
Mereka tidak berguna ketika mereka mendorong pengembang untuk menguji wrapper-trivial, markup statis, atau file pass-through satu baris hanya untuk meningkatkan persentase. Gunakan coverage sebagai alat penemuan. Jika keadaan autentikasi, aksi pembayaran, flag fitur, atau prompt pembaruan tidak memiliki tes, itu adalah tanda. Jika komponen ikon presentasional tidak memiliki tes, biasanya bukan.
Pertanyaan ulasan yang sehat adalah sederhana: apakah tes ini mengurangi risiko rilis?
- Ya: Itu memverifikasi perilaku yang dapat dilihat pengguna pada jalur kritis.
- Mungkin: Itu melindungi logika bisnis yang mudah rusak selama refactor.
- Tidak: Itu mengklaim detail implementasi atau mengulangi nilai tes lain.
Apa yang tidak perlu diuji unit
Banyak panduan React masih tidak menghabiskan waktu yang cukup pada penghapusan. Kesalahan itu penting karena pengujian yang berlebihan dan pengujian detail implementasi menciptakan suite yang rapuh yang dapat melewati tes sementara 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 ini:
- Pengecekan Status Dalam: Jangan Uji
isOpenSaat itu langsung ketika Anda dapat menguji apakah panel terbuka. - Sikap Framework: Janganlah menguji bahwa React telah memanggil efek. Uji hasil dari apa yang perubahan efek itu.
- Struktur Intern Perpustakaan Ketiga Pihak Periksa integrasi Anda dengan tanggal pilih atau router, bukan logika rendering library itu sendiri.
- Satuan yang rusak berlebihan: 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.
A useful heuristic is boundary ownership. Test what your code owns. Don’t test what React, the browser, or a mature library already owns unless your integration layer changes the contract.
Dimana snapshot membantu dan dimana mereka menyakiti
Cukuplah snapshot tidak sia-sia. Mereka hanya mudah digunakan dengan tidak tepat.
Menggunakannya secara berhati-hati untuk komponen dengan output stabil dan sederhana di mana perbedaan struktur luas berarti. Hindari penggunaannya untuk komponen interaktif atau dinamis karena mereka menjadi gangguan. Pengembang berhenti membaca mereka dan mulai memperbarui mereka secara refleksif.
Alternatif yang lebih baik biasanya ada:
- Untuk rendering kondisional, asertkan kehadiran atau ketidakhadiran teks kunci.
- Untuk perubahan visual, asertkan peran, label, atau atribut yang berpengaruh.
- Untuk kesalahan dan fallback, asertkan pesan atau wilayah peringatan yang sebenarnya.
Jika tim Anda membutuhkan proses kualitas yang lebih luas di luar unit test, kompanen yang solid adalah alur kualitas aplikasi yang menganggap tes, pengecekan rilis, dan perencanaan rollback sebagai satu sistem. Perubahan mindset yang memperbaiki kualitas tes paling cepat. Berhenti bertanya berapa banyak tes Anda. Mulai bertanya tentang kegagalan mana yang masih bisa mencapai pengguna.
Mengintegrasikan Tes ke Dalam Pipa CI/CD Berbasis Multi-Platform
Suatu suite uji yang hanya dijalankan pada laptop pengembang adalah saran, bukan kontrol.
Susunan tes menjadi operasional ketika setiap permintaan pull berjalan pada periksaan yang sama di lingkungan bersih dan menghalangi penggabungan ketika periksaan tersebut gagal. Itu terdengar jelas, tapi banyak tim masih meninggalkan celah-celah kritis. Tes berjalan secara manual. Laporan penutupan tidak wajib. Tugas pengemasan dan rilis dimulai sebelum tugas tes selesai. Itu cara kecilnya UI regresi masuk ke dalam kegagalan rilis yang lebih besar.

Setiap pull request harus memicu gate yang sama setiap kali.
Untuk melakukan unit testing React seperti jaring pengaman, CI memerlukan beberapa hal penting:
- Jalankan pada setiap pull request.
- Instal dependensi dari file lock.
- Pakai perintah tes yang sama setiap kali.
- Gagal cepat pada kesalahan tes.
- Publikasikan artefak hanya setelah tes berhasil.
Ini adalah inti dari praktik pengembangan 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
Jangan terlalu berlebihan, dan itu adalah titiknya. Pipa yang paling kuat biasanya adalah yang paling tidak mengejutkan.
Mengapa hal ini lebih penting untuk Capacitor dan Electron
Cross-platform React apps carry more release risk than browser-only apps because the same UI code often ships in different containers with different runtime assumptions.
Beberapa contoh menunjukkan di mana pipeline membantu:
- Aplikasi: Capacitor Web code may pass locally but fail when a plugin bridge, offline state, or app lifecycle edge case changes behavior after packaging.
- Aplikasi Electron: Komponen renderer mungkin bergantung pada API pra-muat, pesan jendela, atau keadaan desktop yang hanya ada jika sengaja ditiru dalam pengujian browser biasa.
- Relasi rilis bersama: Satu bundle yang buruk dapat mempengaruhi beberapa target jika proses pengiriman Anda tidak mengatur publikasi dengan ketat.
That’s why unit tests should run before packaging jobs, and packaging jobs should run before distribution jobs. Each stage narrows risk. Unit tests catch local regressions quickly. Platform packaging verifies environment assumptions. Manual approval or staged rollout handles the final release confidence.
A practical GitHub Actions workflow
A pipa yang lebih matang biasanya membagi tanggung jawab:
- Job uji coba: Uji unit dan hook yang cepat
- Job bangun: Bangun produksi hanya setelah tes berhasil
- Job paket: Capacitor sinkronisasi, pengemasan Electron, atau pengemasan artefak
- Job rilis: Hanya rilis dari cabang atau tag yang disetujui
Untuk tim yang mengirimkan pembaruan hidup ke Capacitor atau aplikasi Electron, ini adalah tempat alat rilis berperan. Salah satu pilihan dalam alur kerja tersebut adalah Capgoyang menerbitkan paket web yang ditandatangani untuk aplikasi CapacitorJS dan Electron dengan dukungan rollback dan kontrol rollout berdasarkan saluran. Dalam prakteknya, itu berarti job uji React Anda dapat berfungsi sebagai pintu keras pertama sebelum paket web apa pun dipromosikan ke pengiriman staging atau produksi.
Operasional aturan ini sederhana. Jangan biarkan infrastruktur rilis menggantikan tes yang lemah. Gunakan infrastruktur rilis setelah tes yang dapat diandalkan telah menyaring perubahan buruk.
Sistem tes yang dapat diandalkan mengubah perilaku tim. Para insinyur bergabung dengan kurang banyak keraguan. Para pemeriksa fokus pada kasus tepi 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 mengirim React melalui Capacitor atau Electron, keamanan rilis bergantung pada lebih dari tes lokal hijau. Capgo memberikan tim cara yang dikendalikan untuk mempublikasikan pembaruan web yang ditandatangani, targetkan saluran perluasan, dan kembali ke bundle buruk tanpa menunggu tinjauan toko, yang sesuai dengan alami di belakang pipeline CI yang sudah memerlukan melewati tes unit sebelum deploymen.