Anda mengubah tampilan UI kecil sebelum makan siang. Tampaknya tidak berbahaya. Label tombol berubah, render kondisional menjadi lebih sederhana, dan hook bantuan mengambil cabang baru. Pull request bersih, review cepat, dan deploy keluar.
Satu jam kemudian, tim dukungan melaporkan bahwa login gagal di satu platform. Web terlihat baik. Shell desktop memiliki jalur render ketinggalan zaman. Build 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 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, kereta rilis, hotfix, dan pengemasan lintas platform adalah bagian yang sulit. render()Applikasi React gagal karena tim lupa cara memanggil
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.
Pengujian unit modern React berfungsi ketika berperilaku seperti sistem keamanan. Feedback cepat lokal. Periksaan deterministik di CI. Batasan yang jelas di sekitar apa yang termasuk dalam pengujian unit dan apa yang tidak.
- Masalah ini semakin penting ketika kode React yang sama dikirim melalui browser, __CAPGO_KEEP_0__ kontainer, atau shell Electron.
- Mengapa Unit Testing React Adalah Jaringan Keamanan Terbaik Anda
- Tambahkan file pengaturan yang akan digunakan oleh suite Anda
- Menguji Hook-Hook Kustom dan Logika Aplikasi
- Menguasai Teknik-Teknik Lanjutan Mocking dan Async
- Meningkatkan Kualitas dan Strategi Pengujian
- Mengintegrasikan Uji Coba ke dalam 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 dipercaya pengguna telah berubah. Tombol yang dinonaktifkan menjadi dapat diklik. Status muatan tidak pernah hilang. Pesan pengganti hilang setelah refactor. Kesalahan-kesalahan kecil di code dan mahal di produksi.
Pengujian React berubah dalam cara yang penting ketika Pengujian React Library menjadi model utama untuk menguji perilaku bukanlah bagian internalmendorong tim ke arah uji coba yang meniru 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 dipisahkan. 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:
- Hasil rendering: Apakah pengguna melihat teks, label, status, atau fallback yang benar?
- Penggunaan 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:
- Intern komponen: Bentuk negara, metode privat, dan props implementasi saja
- Mechanisme kerangka kerja: Apakah React memperbarui hook secara internal sesuai dengan harapan Anda
- Detail anak: Markup yang dimiliki oleh komponen yang terikat yang tidak Anda maksud untuk memverifikasi di sini
Aturan praktis: Jika Anda dapat memperbaiki 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 membuktikan bahwa aplikasi seluruhnya berfungsi dari awal hingga akhir. Mereka adalah lapisan cepat yang menangkap kembali regresi sebelum Anda memerlukan tes browser-level atau validasi perangkat-level. Itulah mengapa mereka adalah garis pertama pertahanan dalam setiap stack otomatisasi tes untuk aplikasi produksi Ketika tim React sering mengirimkan, kepercayaan datang dari pembagian kerja ini. Tes unit menangkap regresi lokal dengan cepat. Tes integrasi memverifikasi sambungan. Tes akhir-ke-awal memastikan jalur kritis. Lebih baik melewati lapisan unit, dan segala sesuatu yang lebih lambat di bawahnya harus membawa terlalu banyak beban.
Mengatur Lingkungan Tes Modern React Anda
Suatu lingkungan tes yang rapuh menciptakan tes yang flaky sebelum Anda menulis asseri tunggal. Banyak pengembang menyalahkan Jest, jsdom, atau React ketika masalah yang mendasarinya adalah konfigurasi yang tidak konsisten di seluruh mesin lokal dan CI. Solusinya adalah membuat lingkungan menjadi membosankan. Membosankan adalah baik di sini
Suatu tempat kerja yang bersih menampilkan komputer monitor yang menampilkan tes unit React __CAPGO_KEEP_0__ di dalam __CAPGO_KEEP_1__ editor

__CAPGO_KEEP_0__
Untuk sebuah aplikasi React modern, terutama yang dibuat dengan Vite, konfigurasi dasar harus mencakup:
- Sebuah pengujian runner: Jest tetap umum, terutama dalam kodebasis React yang lebih tua dan stack CI perusahaan.
- Suatu lingkungan seperti browser:
jsdombiarkan tes komponen menghasilkan output DOM. - Utilitas Testing Library:
@testing-library/reactdan@testing-library/jest-dom - Satu entrypoint pengaturan tunggal: Satu file untuk mendaftarkan matcher dan mock global
Alur kerja utama yang panduan pengujian React kuatkan adalah sederhana: render komponen dalam lingkungan jsdom, tanya UI dengan selektor seperti getByText atau getByRole, aktifkan interaksi, dan asertikan perubahan DOM, seperti yang dijelaskan di Dokumentasi pengujian React. Jika alur kerja 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. Poin bukanlah transformer. Poinnya adalah konsistensi. Pilih satu jalur dan standarisasi di repositori. Jika Anda ingin referensi rekanan yang baik untuk konvensi pengujian JavaScript yang lebih luas, Capgo’s panduan pengujian unit JavaScript adalah dokumen pengalihan tim yang berguna.
Tambahkan file konfigurasi yang akan digunakan oleh suite Anda
Sekaligus setupTests.js menghemat banyak kebisingan yang diulang-ulang:
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, ResizeObserver, atau IntersectionObserver, jika library komponen Anda mengharapkannya.
Tanpa ini, pengembang akan memperbaiki global secara ad hoc. 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. Simpan skrip eksplisit:
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:ci": "jest --runInBand --coverage"
}
}
Petunjuk singkat membantu anggota tim baru mendapatkan basis yang sama dengan cepat:
Pilihan pengaturan yang paling berdampak adalah disiplin seputar pengaturan 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 perlu, semakin andal sistem Anda.
Menggunakan 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 adalah masih yang tepat: render komponen, tanyakan UI dengan selektor yang berpusat pada pengguna, trigger interaksi, dan asert perubahan DOM hasilnya, yang menjaga tes jauh dari detail implementasi seperti state atau props, seperti yang dijelaskan dalam Petunjuk Pengujian React. Triknya adalah menerapkan pola tersebut dengan bijak.
Tes accordion seperti pengguna menggunakan itu
Ambil komponen dasar. Komponen ini menampilkan tombol dengan judul. Konten panel dimulai disembunyikan. Klik tombol mengungkapkan konten dan memperbarui status aksesibilitas. Accordion Itu sudah cukup perilaku untuk beberapa tes berguna:
Pengrenderan awal menampilkan judul tetapi tidak konten.
- Klik tombol pengungkit mengungkapkan konten.
- Klik lagi mengembalikannya.
- Atribut aksesibilitas mencerminkan status yang terlihat.
- Poin terakhir itu seringkali dilupakan. Jika komponen Anda menggunakan , atau struktur berdasarkan peran, verifikasi mereka. Mereka bukanlah detail implementasi. Mereka adalah bagian dari kontrak yang terlihat oleh pengguna.
Tes komponen terbaik membaca seperti laporan bug yang tidak pernah Anda inginkan. aria-expanded, aria-controls__CAPGO_KEEP_0__
__CAPGO_KEEP_0__
Memilih kueri berdasarkan tujuan
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 | Menegaskan bahwa tombol atau judul sudah ada di layar |
queryBy |
Mengembalikan elemen segera | Mengembalikan null |
Menegaskan bahwa konten disembunyikan tidak ada sebelum interaksi |
findBy |
Mengatasi ketika elemen muncul | Menolak setelah menunggu | Tetapkan konten yang dimuat secara async muncul setelah fetch atau pembaruan yang tertunda |
Model mental yang sederhana membantu:
- Gunakan
getByuntuk hal-hal yang sudah ada sebelumnya. - Gunakan
queryByuntuk hal-hal yang belum ada sebelumnya. - Gunakan
findByketika UI berubah kemudian.
Jika sebuah tes dimulai dengan findBy untuk segalanya, biasanya berarti penulis tidak yakin kapan komponen diperbarui. Ketidakpastian tersebut menjadi fluktuasi kemudian.
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 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 yang telah dipanggil. Tidak ada snapshot dari pohon yang di-render secara keseluruhan. Tes-tes tersebut akan menambahkan biaya perawatan, bukan kepercayaan. setOpen Beberapa kebiasaan membuat tes komponen lebih kuat:
Lebih baik menggunakan kueri berdasarkan peran:
- Tombol, judul, dialog, peringatan, dan input biasanya harus ditemukan berdasarkan peran. Tetapkan setiap tes sempit:
- Satu perilaku yang dapat dilihat oleh pengguna per tes menjaga kebocoran dapat dibaca. Nama tes setelah hasil:
- “mengupdate aria-expanded ketika dibuka” jauh lebih berguna daripada “berfungsi dengan benar.” A practical accordion example
If suatu komponen sulit untuk diuji melalui DOM, itu sering kali menunjukkan masalah desain. Mungkin itu menyembunyikan keadaan di tempat yang salah. Mungkin itu kurang memiliki markup semantik. Tes yang baik sering kali mendorong tim ke 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 formatasi 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 menjalankan 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 itu 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 antarmuka yang digunakan bersama di antara aplikasi, sistem desain, atau alat bantu internal. Jika Anda merancang perilaku yang dapat digunakan kembali dengan niat komersial, sumber daya pada hook untuk produk pembuat Dapat membantu mengatur hook sebagai blok bangunan yang dijual daripada hanya detail implementasi.
Logika murni harus tetap murni dalam tes
Tidak semua memerlukan jsdom, React, atau Testing Library. Jika sebuah fungsi bersih, tesnya dengan Jest sederhana 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 yang di-render, jangan berikan padanya. Alat-alat React menambahkan biaya. Jaga logika bisnis tes kecil, cepat, dan dekat dengan fungsi yang mereka verifikasi.
Pemisahan praktis yang baik:
- Hook: Gunakan
renderHook,act(), dan penyedia wrapper ketika dibutuhkan. - Utilitas: Gunakan Jest biasa dan tidak DOM.
- Logika lintas potong yang berubah-ubah: Tariknya ke bantuan tes yang dapat diuji ketika tes komponen mulai melakukan terlalu banyak.
Tim seringkali melebih-lebihkan tes komponen dengan logika asertasi yang lebih rendah di tangga. Mengeluarkan logika itu memberikan dua manfaat. Tes komponen menjadi lebih bersih, dan tes logika menjadi lebih cepat.
Menguasai Teknik Canggih Mocking dan Synchronous
Sebagian besar suite React yang tidak dapat diandalkan rusak di dua tempat. Mereka rusak di batasan ketergantungan, dan mereka rusak di sekitar waktu.
Itu adalah mengapa tes asinkron dan mocking adalah garis pemisah antara suite tes mainan dan satu yang dapat dipercaya sebelum rilis. Satu analisis atributkan 46,5% dari ketidakstabilan tes ke masalah lingkungan atau terkait sumber daya seperti waktu asinkron di analisis unit testing React ini. Di aplikasi React, itu secara langsung berhubungan dengan transisi keadaan, rendering yang tertunda, UI yang dikemudikan oleh jaringan, dan tes yang menebak bukan menunggu secara deterministik.

Buat batasan, bukan setiap lapisan
Cara termudah untuk menulis tes yang menipu adalah dengan memalsukan setengah pohon komponen Anda dan kemudian mengklaim bahwa mock Anda sendiri berhasil.
Untuk komponen yang mengambil data akun, silakan memalsukan klien jaringan atau modul API. Jangan memalsukan hook, komponen anak baris, spinner loading, dan tiga fungsi utilitas kecuali tes benar-benar memerlukan isolasi pada sambungan-sambungan tersebut.
Gunakan set aturan ini:
- Mock layanan eksternal: Klien HTTP, analitik, API browser-only, jembatan native
- Mock API platform yang tidak stabil:
matchMedia, timer, interface preload Electron, plugin Capacitor ketika tidak tersedia di jsdom - Hindari memalsukan internasional Anda secara default: hook kustom, anak-anak sederhana, utilitas lokal
Jika tes melewati karena semua bagian yang sulit diganti dengan palsu, maka tidak ada kepercayaan diri yang diperoleh.
Untuk tim yang ingin contoh dan pola seputar API runner, gunakan Capgo Kategori Jest adalah sebuah referensi library yang sangat berguna, terutama ketika proses onboarding para developer yang sudah mengenal React tapi belum mengerti mekanisme testing.
Jika tes async gagal, maka biasanya karena waktu yang tidak jelas.
Gagalnya tes async biasanya disebabkan oleh salah satu dari tiga kesalahan berikut:
- Jika tes mengklaim terlalu cepat.
- Jika tes menunggu dengan pengaturan waktu yang acak.
- Jika komponen mengupdate lebih dari sekali, tapi tes hanya menggambarkan satu transisi.
Biasanya, tes async stabil 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();
});
Gunakan findBy ketika penampilan elemen tertentu adalah acara yang Anda pedulikan. Gunakan 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.
Ecosistem pengujian React juga mengharapkan Anda untuk menghormati act() semantik seputar pembaruan. Library Pengujian menangani banyak hal ini untuk Anda, tetapi jika Anda mengemudi state secara manual atau maju timer, Anda masih perlu berpikir tentang kapan pembaruan mengalir.
Tahu alat mocking mana yang harus digunakan
Alat mocking yang berbeda menyelesaikan masalah yang berbeda:
| Alat | Penggunaan terbaik | Kesalahan umum |
|---|---|---|
jest.fn() |
Panggilan balik palsu yang berdiri sendiri atau fungsi yang diinjeksikan | Menggunakan untuk menggantikan modul yang utuh ketika panggilan balik yang sederhana sudah cukup |
jest.spyOn() |
Amati atau ubah satu metode pada objek atau modul yang nyata | Lupa untuk memulihkan implementasi asli |
jest.mock() |
Ganti dependensi modul di batas impor | Menggambarkan modul besar secara default dan kehilangan perilaku yang bermakna |
Contoh membantu:
- Cari untuk
jest.fn()ketika komponen menerimaonSubmitprop. - Gunakan
jest.spyOn()ketika Anda perlu memastikanconsole.errormetode penyimpanan, atau satu panggilan API yang diekspor. - Gunakan
jest.mock()ketika mengimpor modul akan mengalami I/O, native code, atau perilaku di luar batas unit.
Salah satu area yang maju banyak panduan tidak menangani 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 anak-anak melempar, asertkan UI fallback yang terlihat. Jika permintaan gagal, asertkan keadaan pemulihan yang terlihat. Jika tombol dinonaktifkan selama pengisian, asertkan juga itu. Itu adalah bug yang pengguna ingat.
Meningkatkan Kualitas dan Strategi Pengujian
Banyak tim masih mengejar koverasi seperti halnya kepercayaan. Tidak demikian.
Anda bisa mencapai target koverasi dan masih melewatkan regresi yang penting. Suatu suite penuh asseri dangkal, snapshot luas, dan internal yang dimock membuat penampilan aman sementara juga meningkatkan biaya perawatan.

Koverasi adalah peta, bukan tujuan
Laporan koverasi 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 melewati satu baris hanya untuk meningkatkan persentase. Tatal koverasi sebagai alat penemuan. Jika status autentikasi, aksi tagihan, flag fitur, atau prompt pembaruan tidak memiliki pengujian, itu adalah tanda. Jika komponen ikon presentasional tidak memiliki pengujian, biasanya bukan.
Pertanyaan review yang sehat adalah sederhana: apakah pengujian ini mengurangi risiko rilis?
- Ya: Pengujian ini memverifikasi perilaku yang dapat dilihat pengguna pada jalur kritis.
- Mungkin: Pengujian ini melindungi logika bisnis yang mudah rusak selama refactor.
- 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 kekurangan. Kesalahan itu penting karena over-mocking dan pengujian detail implementasi membuat 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 uji
isOpenlangsung ketika Anda bisa menguji apakah panel terbuka. - Penggunaan framework: Jangan uji bahwa React 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 perpustakaan.
- Satuan yang terpecah-pecah terlalu banyak: Jika Anda telah memalsukan setiap anak dan bantuan, 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 perpustakaan yang matang sudah miliki kecuali lapisan integrasi Anda mengubah kontrak.
Dimana snapshot membantu dan dimana mereka menyakiti
Snapshot tidak tidak berguna. Mereka hanya mudah digunakan dengan tidak tepat.
Pakai mereka dengan sedikit untuk komponen dengan output stabil, sederhana, di mana perbedaan struktur luas bermakna. Hindari mereka untuk komponen interaktif atau dinamis tinggi 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 berarti.
- Untuk kesalahan dan fallback, asertkan pesan yang sebenarnya atau wilayah peringatan.
If tim team Anda memerlukan proses kualitas yang lebih luas di luar unit test, teman yang solid adalah alur kerja kualitas aplikasi yang menganggap tes, pengecekan 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 menjalankan periksaan yang sama di lingkungan bersih dan menghalangi merge ketika periksaan tersebut gagal. Ini terdengar jelas, tapi banyak tim masih meninggalkan celah-celah kritis. Tes dijalankan secara manual. Laporan penutupan kode adalah opsional. Tugas pengemasan dan rilis dimulai sebelum tugas tes selesai. Itulah cara kecilnya regresi UI masuk ke kegagalan rilis yang lebih besar.
Alur Lima Langkah untuk Mengintegrasikan Tes Otomatis React ke Pipa CI/CD Pengembangan
Permintaan pull harus mengaktifkan pintu gerbang yang sama setiap kali

Jalankan pada setiap permintaan pull
Instal dependensi dari file lock
- Pakai perintah tes yang sama setiap kali
- Integrating Tests into a Cross-Platform CI/CD Pipeline
- A test suite that only runs on a developer laptop is a suggestion, not a control.
- Gagal 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.
Sederhana GitHub Workflow Actions 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 mewah, dan itu poinnya. Pipa yang kuat biasanya adalah yang paling tidak mengejutkan.
Mengapa ini lebih penting untuk Capacitor dan Electron
Aplikasi React yang berbasis multi-platform membawa risiko rilis yang lebih besar daripada aplikasi browser-only karena UI yang sama code seringkali dikirim dalam kontainer yang berbeda dengan asumsi runtime yang berbeda.
Beberapa contoh menunjukkan di mana pipa membantu:
- Capacitor aplikasi: Web code mungkin berhasil secara lokal tetapi gagal ketika jembatan plugin, keadaan offline, atau kasus edge aplikasi siklus hidup mengubah perilaku setelah pengemasan.
- Aplikasi Electron: Komponen renderer mungkin bergantung pada API preload, pesan jendela, atau keadaan desktop yang tidak akan ada dalam pengujian browser biasa kecuali secara sengaja di mock.
- Relasi rilis bersama: Satu bundle buruk dapat mempengaruhi target-target lain jika proses pengiriman Anda tidak mengunci publikasi dengan ketat.
Oleh karena itu, tes unit harus berjalan sebelum pekerjaan pengemasan, dan pekerjaan pengemasan harus berjalan sebelum pekerjaan distribusi. Setiap tahap mempersempit risiko. Tes unit menangkap regresi lokal dengan cepat. Pengemasan platform memverifikasi asumsi lingkungan. Persetujuan manual atau peluncuran berjenjang menangani kepercayaan rilis akhir.
Alur kerja praktis GitHub Actions
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
- Tugas Rilis: Publikasikan hanya dari cabang atau tag yang disetujui
Bagi tim yang mengirimkan pembaruan hidup ke Capacitor atau aplikasi Electron, ini adalah tempat di mana perangkat lunak rilis berperan. Salah satu pilihan dalam alur kerja tersebut adalah Capgo, yang menerbitkan bundle 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 bundle 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 buruk.
If your team ships React through Capacitor or Electron, release safety depends on more than green local tests. Jika tim Anda mengirimkan React melalui Capgo atau Electron, keamanan rilis bergantung pada lebih dari tes lokal hijau. __CAPGO_KEEP_0__