Langkapi ke konten utama

Pengujian Unit React: Panduan Langkah demi Langkah yang Praktis

Belajar uji coba unit React dari pengaturan hingga CI/CD. Panduan ini mencakup Jest, RTL, hook, async code, pemalsuan, dan praktik terbaik untuk aplikasi lintas platform yang kuat.

Unit Testing React: Panduan Praktis End-to-End

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 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.

Suatu tempat kerja yang bersih menampilkan komputer monitor yang menampilkan pengujian unit React code di code editor.

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: jsdom biarkan tes komponen menampilkan output DOM.
  • Fasilitas utilitas Library Pengujian: @testing-library/react dan @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.

  1. Tampilkan awal menampilkan judul tetapi tidak menampilkan isi.
  2. Mengklik tombol trigger menampilkan konten.
  3. Mengklik lagi menyembunyikannya.
  4. 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 getBy untuk hal-hal yang harus sudah ada.
  • Gunakan queryBy untuk hal-hal yang harus tidak ada sebelumnya.
  • Gunakan findBy ketika 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.

Diagram perbandingan menampilkan Teknik Pengujian React yang Lebih Lanjut, secara khusus fokus pada Pemalsuan Ketergantungan versus Pengujian Asinkron.

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:

  1. Tes mengklaim terlalu cepat.
  2. Tes menunggu dengan timer yang acak.
  3. 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 menerima onSubmit prop.
  • Gunakan jest.spyOn() ketika Anda perlu memastikan console.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.

Infografis yang membandingkan manfaat pengujian kualitas versus biaya perawatan tinggi dari suatu suite pengujian kuantitas.

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 isOpen Saat 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.

A flowchart lima langkah yang menggambarkan proses mengintegrasikan tes otomatis React ke dalam pipeline pengembangan CI/CD.

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:

  1. Job uji coba: Uji unit dan hook yang cepat
  2. Job bangun: Bangun produksi hanya setelah tes berhasil
  3. Job paket: Capacitor sinkronisasi, pengemasan Electron, atau pengemasan artefak
  4. 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.

Update terus untuk Capacitor aplikasi

Ketika bug layer web masih aktif, kirimkan perbaikan melalui Capgo daripada menunggu hari-hari untuk persetujuan toko aplikasi. Pengguna mendapatkan update di latar belakang sementara perubahan native tetap dalam jalur review normal.

dukungan manusia dari Martin

Mulai Sekarang

Terbaru dari Blog Kami

Capgo memberikan Anda wawasan terbaik yang Anda butuhkan untuk membuat aplikasi mobile profesional sejati.