Rumah __CAPGO_KEEP_0__

Unit Testing React: Panduan Langkah demi Langkah yang Praktis

Belajar unit testing React dari setup hingga CI/CD. Panduan ini membahas Jest, RTL, hook, async code, mocking, dan praktik terbaik untuk aplikasi lintas platform yang kuat.

Martin Donadieu

Martin Donadieu

Pengembang Konten

Unit Testing React: Panduan Langkah demi Langkah yang Praktis

Anda menerapkan perubahan UI kecil sebelum makan siang. Terlihat 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 tidak berfungsi 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, peluncuran, patch, dan pengemasan multi-platform adalah bagian yang sulit. Aplikasi React tidak gagal karena tim lupa cara memanggil render(). Mereka gagal karena tes mengarah ke detail implementasi, perilaku asyncus disembunyikan, dan CI menganggap testing sebagai kotak centang daripada 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.

Hal ini lebih penting lagi ketika kode React yang sama dikirim melalui browser, __CAPGO_KEEP_0__ kontainer, atau shell Electron.

Mengapa Unit Testing React Adalah Jaringan Keamanan Terbaik Anda

Uji unit mendapatkan keuntungannya ketika mereka menangkap kesalahan yang Anda percayai 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 yang sedang dimuat 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 internal, yang mendorong tim menuju uji coba 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 terbagi. 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, keadaan, 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 hanya
  • Mekanisme 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 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 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 otomatisasi tes untuk aplikasi produksi Untuk tim React yang sering mengirimkan, kepercayaan datang dari pembagian kerja ini. Tes unit menangkap regresi lokal dengan cepat. Tes integrasi memverifikasi sambungan. Tes akhir-ke-akhir memastikan jalur kritis. Lebih baik melewati lapisan unit, dan segala sesuatu yang lebih lambat di bawahnya harus membawa beban yang terlalu berat.

Mengatur Lingkungan Tes React Modern 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 sebenarnya adalah konfigurasi yang tidak konsisten di antara 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

A clean workspace featuring a computer monitor displaying React unit testing code in a code editor.

__CAPGO_KEEP_0__

Aplikasi React modern, terutama yang dibuat dengan Vite, harus memiliki konfigurasi dasar yang mencakup:

  • Runner tes: Jest masih umum, terutama dalam kodebase React yang lebih tua dan stack CI perusahaan.
  • Lingkungan seperti browser: jsdom untuk memungkinkan tes komponen menampilkan output DOM.
  • Fasilitas utilitas Library Testing: @testing-library/react dan @testing-library/jest-dom
  • Entri pintu masuk setup tunggal: Satu file untuk mendaftarkan matcher dan mock global

Arus kerja utama yang dipertahankan oleh panduan tes React adalah sederhana: render komponen dalam lingkungan jsdom, tanya UI dengan selektor seperti getByText atau getByRoleaktifkan interaksi, dan klaim perubahan DOM, seperti yang dijelaskan di Referensi Dokumentasi Pengujian ReactJika 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 Petunjuk Pengujian Satuan JavaScript adalah dokumen pengalihan tim yang berguna.

Tambahkan file konfigurasi yang akan digunakan oleh suite Anda

Konfigurasi yang tepat 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, seperti matchMedia, ResizeObserver, atau IntersectionObserver, jika library komponen Anda mengharapkannya.

Tanpa ini, pengembang akan memperbaiki global secara ad hoc. Hal ini menciptakan tes yang tidak konsisten dan gagal yang sulit untuk diikuti. Pada saat satu orang menjalankan run lokal dan 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 dalam konfigurasi. Masukkan mock lingkungan 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 dibutuhkan oleh setiap tes, semakin dapat diandalkan sistem Anda.

Membuat Tes Komponen yang Bermakna

Organisasi tidak memiliki masalah menulis tes. Mereka memiliki masalah menulis tes yang masih berarti enam bulan kemudian.

Polanya standar untuk menguji komponen React adalah masih yang tepat: render komponen, tanyakan UI dengan selektor yang berpusat pada pengguna, trigger interaksi, dan asertikan perubahan DOM yang dihasilkan, yang menjaga tes jauh dari detail implementasi seperti state atau props, seperti yang dijelaskan dalam guide pengujian React. Triknya adalah menerapkan pola tersebut dengan bijak.

Tes accordion seperti pengguna menggunakan fiturnya

Ambil komponen dasar. Accordion Komponen ini menampilkan tombol dengan judul. Isi panel dimulai disembunyikan. Klik tombol mengungkapkan isi dan memperbarui status aksesibilitas.

Itu sudah cukup perilaku untuk beberapa tes yang berguna:

  1. Pengrenderan awal menampilkan judul tetapi tidak menampilkan isi.
  2. Klik tombol pengaktif mengungkapkan isi.
  3. Klik lagi mengembalikannya.
  4. Atribut aksesibilitas mencerminkan status yang terlihat.

Poin terakhir seringkali dilupakan. Jika komponen Anda menggunakan aria-expanded, aria-controls, atau struktur berdasarkan peran, verifikasi mereka. Mereka bukanlah detail implementasi. Mereka adalah bagian dari kontrak yang dihadapi pengguna.

Komponen tes terbaik membaca seperti laporan bug yang tidak pernah Anda inginkan.

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

Jenis Kueri Ketika Element Ditemukan Ketika Element Tidak Ditemukan Contoh Penggunaan
getBy Mengembalikan element segera Mengembalikan kesalahan segera Tetapkan tombol atau judul harus sudah ada di layar
queryBy Mengembalikan element segera Mengembalikan null Tetapkan konten disembunyikan tidak ada sebelum interaksi
findBy Mengatasi ketika elemen muncul Menolak setelah menunggu Mengaku konten yang dimuat secara async muncul setelah fetch atau pembaruan yang tertunda

Model mental sederhana membantu:

  • Gunakan getBy untuk hal-hal yang sudah harus ada.
  • Gunakan queryBy untuk hal-hal yang belum harus ada.
  • Gunakan findBy ketika UI berubah kemudian.

Jika sebuah tes dimulai dengan findBy untuk segalanya, biasanya berarti penulis tidak yakin kapan komponen diperbarui. Ketidakpastian tersebut menjadi flaksitas kemudian.

A contoh accordion yang praktis

Sini ada 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>
  );
}

Sini 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');
});

Apa yang hilang pun penting. Tidak ada asseri terhadap keadaan internal. Tidak ada pengecekan apakah fungsi tertentu telah dipanggil. Tidak ada snapshot dari seluruh pohon yang di-render. Tes-tes seperti itu akan menambah biaya perawatan, bukan kepercayaan. setOpen Beberapa kebiasaan membuat tes komponen lebih kuat:

Lebih baik gunakan kueri berdasarkan peran:

  • Botton, judul, dialog, peringatan, dan input biasanya dapat ditemukan dengan menggunakan peran. Pisahkan setiap tes secara sempit:
  • Satu perilaku yang dapat dilihat pengguna per tes membuat kegagalan lebih mudah dibaca. Beritahu tes sesuai dengan hasilnya:
  • “mengupdate aria-expanded ketika dibuka” jauh lebih berguna daripada “berfungsi dengan benar.” __CAPGO_KEEP_0__

Jika sebuah komponen sulit diuji melalui DOM, itu sering kali menunjukkan masalah desain. Mungkin itu menyembunyikan status di tempat yang salah. Mungkin itu kurang memiliki markup semantik. Tes yang baik sering kali mendorong tim ke komponen yang lebih baik.

Menguji Hook-Hook Kustom dan Logika Aplikasi

Aplikasi React menyembunyikan banyak perilaku penting di luar komponen. Transisi status 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 bisa 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 status 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 };
}

Ujiannya 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);
});

Uji 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 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 bisa membantu menggambarkan hook sebagai blok bangunan yang dijual daripada hanya detail implementasi.

Logika murni harus tetap murni dalam tes

tidak semua hal memerlukan jsdom, React, atau Testing Library. Jika sebuah fungsi bersih, tesnya dengan 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 React khusus menambahkan beban. Jaga logika bisnis tes kecil, cepat, dan dekat dengan fungsi yang mereka verifikasi.

Pemisahan praktis yang baik adalah:

  • Hook: Pakai renderHook, act(), dan penyedia wrapper ketika diperlukan.
  • Utilitas: Gunakan Jest biasa dan tidak DOM.
  • Logika yang berubah-ubah: Tariknya ke helper yang dapat diuji ketika tes komponen mulai melakukan terlalu banyak logika.

Banyak tim seringkali memenuhi tes komponen dengan asseri 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 Lanjutan Mocking dan Async

Sistem uji React yang paling tidak dapat diandalkan patah di dua tempat. Mereka patah di batas ketergantungan, dan mereka patah di sekitar waktu.

Itu mengapa uji async dan mocking adalah garis pembagi antara suatu suite uji mainan dan satu yang dapat dipercaya sebelum rilis. Satu analisis mengatribusikan 46,5% dari ketidakstabilan uji ke masalah lingkungan atau terkait sumber daya seperti waktu async di analisis uji unit React ini. Pada 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.

Tabel perbandingan menampilkan Teknik Uji React Lanjutan, secara spesifik fokus pada Mocking Dependencies versus Uji Asynchronous.

Menggambarkan batasan, bukan setiap lapisan

Jalan tercepat untuk menulis tes yang menipu adalah dengan menggambarkan setengah pohon komponen Anda dan kemudian mengklaim bahwa mock Anda sendiri berhasil.

Untuk komponen yang mengambil data akun, mock klien jaringan atau modul API. Jangan mock hook, komponen baris anak, spinner loading, dan tiga fungsi utilitas kecuali tes benar-benar memerlukan isolasi di sambungan-sambungan tersebut.

Pakai set aturan ini:

  • Menggambarkan layanan eksternal: Klien HTTP, analitik, API browser-only, jembatan native
  • Menggambarkan API platform tidak stabil: matchMediatimer, interface preload Electron, plugin Capacitor ketika tidak tersedia di jsdom
  • Hindari menggambarkan internasional Anda secara default: hook kustom, anak-anak sederhana, utilitas lokal

Jika tes melewati karena semua bagian yang sulit digantikan dengan palsu, itu tidak akan memberikan Anda banyak kepercayaan diri untuk merilis.

Untuk tim yang ingin contoh dan pola seputar API runner, Capgo testing tutorials adalah sebuah referensi perpustakaan yang praktis, terutama ketika mengonboard pengembang yang tahu React tapi belum mengerti mekanisme testing.

Test async gagal ketika waktu yang tidak jelas

Kegagalan async biasanya berasal dari salah satu dari tiga kesalahan:

  1. Test mengklaim terlalu cepat.
  2. Test menunggu dengan timer yang acak.
  3. Komponen diperbarui lebih dari sekali, tapi test hanya menggambarkan satu transisi.

Test 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();
});

Gunakan findBy ketika penampilan elemen satu adalah acara yang Anda pedulikan. Gunakan waitFor ketika kondisi lebih luas atau keadaan tidak dapat 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 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-beda menyelesaikan masalah yang berbeda-beda:

Alat Penggunaan terbaik Kesalahan umum
jest.fn() Panggilan balik palsu yang berdiri sendiri atau fungsi yang diinjeksikan Menggunakan alat ini untuk menggantikan modul yang utuh ketika panggilan balik sederhana sudah cukup
jest.spyOn() Melihat atau menggantikan satu metode pada objek atau modul yang nyata Mengingat untuk memulihkan implementasi asli
jest.mock() Ganti dependensi modul di batas impor Menggantikan modul besar secara default dan kehilangan perilaku yang bermakna

Contoh membantu:

  • Cari jest.fn() ketika komponen mengambil onSubmit prop.
  • Gunakan jest.spyOn() ketika Anda perlu memastikan console.error, metode penyimpanan, atau satu panggilan API yang diekspor.
  • Gunakan jest.mock() ketika mengimpor modul akan mengenai I/O, native code, atau perilaku di luar batas unit.

Bidang canggih yang banyak panduan tidak layani 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. Tidaklah demikian.

Anda bisa mencapai target koverasi dan masih melewatkan regresi yang penting. Sebuah suite penuh asseri dangkal, snapshot luas, dan internal yang dimock membuat penampilan keamanan sementara juga meningkatkan biaya perawatan.

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

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. Tatalah 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 bukanlah hal yang penting.

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

Banyak panduan React masih tidak menghabiskan waktu yang cukup untuk kekurangan. Kesalahan itu penting karena over-mocking 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 dalam React.

Lepaskan atau sangat limitkan pola-pola berikut:

  • Pengakuan keadaan internal: Jangan uji isOpen langsung ketika Anda bisa menguji apakah panel terbuka.
  • Penggunaan framework: Jangan uji 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 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 secara tidak tepat.

Pakai mereka dengan sedikit untuk komponen dengan output stabil dan sederhana di mana perbedaan struktur luas bermakna. Hindari mereka untuk komponen interaktif atau dinamis sangat karena mereka menjadi kebisingan. Pengembang berhenti membaca mereka dan mulai memperbarui mereka secara refleksif.

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

If tim Anda memerlukan proses kualitas yang lebih luas di luar unit test, teman yang solid adalah alur kerja jaminan 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 berjalan pada periksaan yang sama di lingkungan bersih dan menghalangi penggabungan ketika periksaan gagal. Ini terdengar jelas, tapi banyak tim masih meninggalkan celah-celah kritis. Tes berjalan secara manual. Laporan penutupan koverase adalah opsional. Tugas pengemasan dan rilis dimulai sebelum tugas tes selesai. Itulah cara kecil kesalahan UI masuk ke kegagalan rilis yang lebih besar.

Diagram Alir Lima Langkah Integrasi Tes Otomatis React ke Pipa CI/CD Pengembangan

Permintaan pull harus mengaktifkan pintu gerbang yang sama setiap kali

Untuk melakukan unit testing React seperti jaringan keselamatan, CI memerlukan beberapa hal penting:

Jalankan pada setiap permintaan pull

Instal dependensi dari file lock

  • Pakai perintah tes yang sama setiap kali
  • Integrasi tes ke alur kerja CI/CD
  • Jangan biarkan tes berjalan secara manual
  • 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.

Alur kerja GitHub yang sederhana 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 menarik, 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 lebih besar pada saat rilis daripada aplikasi browser-only karena UI yang sama code seringkali berlayar di kontainer yang berbeda dengan asumsi runtime yang berbeda.

Beberapa contoh menunjukkan di mana pipa membantu:

  • Capacitor apps: Aplikasi web code mungkin berhasil secara lokal tetapi gagal ketika ada perubahan perilaku jembatan plugin, keadaan offline, atau kasus edge app lifecycle 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 ditiru.
  • Relasi rilis bersama: Satu bundle yang buruk dapat mempengaruhi target-target lain jika proses pengiriman Anda tidak mengunci publikasi dengan ketat.

Itulah mengapa 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 matang biasanya membagi tanggung jawab:

  1. Pekerjaan tes: Tes unit dan hook yang cepat
  2. Pekerjaan pembangunan: Pembangunan produksi hanya setelah tes berhasil
  3. Pekerjaan pengemasan: Capacitor sinkronisasi, pengemasan Electron, atau penggabungan artefak
  4. Tugas Rilis: Publikasikan hanya dari cabang atau tag yang disetujui

Bagi tim yang mengirimkan pembaruan langsung 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 peran 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 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. Itu adalah 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 peran, dan mengembalikan bundle buruk tanpa menunggu tinjauan toko, yang sesuai dengan alur kerja CI yang sudah memerlukan tes unit yang melewati sebelum pengiriman.

Pembaruan Langsung untuk Aplikasi Capacitor

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

Mulai Sekarang

Terbaru dari Blog Kami

Capgo memberikan Anda wawasan terbaik yang Anda butuhkan untuk menciptakan aplikasi mobile profesional yang sebenarnya.