Rumah __CAPGO_KEEP_0__

Menguasai Pengujian Satuan React dari Setup hingga CI/CD.

Pelajari pengujian satuan React dari setup hingga CI/CD. Panduan ini mencakup Jest, RTL, hook, async code, mocking, dan praktik terbaik untuk aplikasi lintas platform yang kuat.

Martin Donadieu

Martin Donadieu

Content Marketer

Panduan Praktis Uji Unit React: Langkah demi Langkah

Kamu mengubah tampilan UI kecil sebelum makan siang. Tampaknya tidak berbahaya. Label tombol berubah, render kondisional diperbarui, dan hook bantuan memilih cabang baru. Permintaan pull bersih, tinjauan cepat, dan deploy keluar.

Sejam kemudian, dukungan melaporkan bahwa login tidak berfungsi di satu platform. Web terlihat baik. Shell desktop memiliki jalur render ketinggalan. Bangun mobile berperilaku berbeda setelah perubahan 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 uji unit React di tim produksi adalah menulis beberapa tes yang berhasil bukanlah hal yang sulit. Namun, membangun suatu suite yang masih melindungi Anda selama refactor, kereta rilis, hotfix, dan pengemasan lintas platform adalah bagian yang sulit. render()Aplikasi 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. Periksa deterministik di CI. Batasan jelas di sekitar apa yang termasuk dalam tes unit dan apa yang tidak.

Mengapa Pengujian Unit React adalah Jaringan Keamanan Terbaik Anda

Unit test memperoleh kegunaannya ketika mereka menangkap kesalahan yang Anda yakin tidak akan terjadi. Di React, biasanya berarti komponen masih menampilkan, tetapi perilaku yang digunakan 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.

React testing berubah dalam cara yang penting ketika React Testing Library menjadi model mainstream untuk menguji perilaku bukan internal, mendorong tim menuju tes yang mengacu pada perilaku pengguna bukan props atau keadaan komponen, seperti yang terlihat dalam panduan testing React Native di Ringkasan testing React Native. Perubahan itu penting karena React code selalu berubah. Hooks berpindah. Komponen dipisahkan. Konteks diperkenalkan. Tes yang terkait dengan struktur internal rusak selama refactor yang sehat. Tes yang terkait dengan perilaku yang dapat dilihat biasanya bertahan.

Apa yang harus dilindungi oleh unit test

Unit test yang baik melindungi satu kontrak kecil:

  • Tampilan yang dihasilkan: Apakah pengguna melihat teks, label, keadaan, atau pengganti yang benar?
  • Perilaku interaksi: Apakah klik, ketik, atau toggle mengubah UI dengan benar?
  • Pengelolaan batas: Apakah komponen berperilaku dengan benar ketika menerima input yang diharapkan, data yang hilang, atau jalur kesalahan?

Tes yang lemah melindungi hal yang salah:

  • Rahasia komponen: Bentuk negara, metode pribadi, atribut implementasi hanya
  • Mekanisme kerja 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 terikat yang Anda tidak ingin memverifikasi di sini

Aturan praktis: Jika Anda dapat meredefinisikan 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 membuktikan bahwa aplikasi berjalan secara keseluruhan dari awal hingga akhir. Mereka adalah lapisan cepat yang menangkap regresi sebelum Anda memerlukan tes peramban-level atau validasi perangkat-level. Itulah mengapa mereka adalah garis pertama pertahanan dalam setiap stack yang masuk akal. pengujian otomatis untuk aplikasi produksi.

Untuk tim React yang sering mengirimkan, kepercayaan datang dari pembagian kerja ini. Uji unit menangkap kembali 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 mengizinkan tes komponen untuk menampilkan output DOM.
  • Utilitas Testing Library: @testing-library/react And @testing-library/jest-dom
  • A setup entry point tunggal: Satu file untuk mendaftarkan matcher dan mock global

Arus kerja utama yang panduan testing React kuatkan adalah sederhana: render komponen dalam lingkungan jsdom, tanya UI dengan selektor seperti getByText atau getByRole, interaksi, dan klaim perubahan DOM, seperti yang dijelaskan dalam dokumentasi testing React . Arus kerja ini hanya dapat dipercaya jika setiap mesin menjalankan lingkungan testing yang samaA setup Jest yang praktis biasanya terlihat seperti ini:

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 testing JavaScript yang lebih luas, panduan unit testing __CAPGO_KEEP_0__ dalam guide JavaScript

// 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 Jest setup yang umum adalah: Jika Anda menggunakan SWC, itu tidak masalah. Poin bukanlah transformer. Poinnya adalah konsistensi. Pilih satu jalur dan standarisasi di repositori.

Tambahkan file pengaturan yang suite Anda akan bergantung pada

Sebuah yang tepat setupTests.js menyimpan 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 kegagalan yang sulit untuk diikuti. Salah satu orang’s run lokal berhasil karena mereka menambahkan mock manual di file. CI gagal karena pengaturan tidak dibagikan.

Jaga 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 kegagalan yang tidak terduga setelah merge. Jaga 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 individual setiap tes membutuhkan, semakin andal sistem Anda menjadi.

Menulis Uji Coba Komponen yang Bermakna

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

Gaya standar untuk menguji komponen React secara unit masih yang benar: render komponen, tanyakan UI dengan selektor yang berpusat pada pengguna, aktifkan interaksi, dan asert perubahan DOM hasilnya, yang menjaga uji coba jauh dari detail implementasi seperti keadaan atau atribut, seperti yang dijelaskan dalam Pedoman Uji Coba React. Triknya adalah menerapkan pola tersebut dengan keterbatasan.

Uji accordion seperti pengguna menggunakan komponen tersebut

Ambil komponen dasar. Komponen tersebut menampilkan tombol dengan judul. Konten panel dimulai disembunyikan. Klik tombol menampilkan konten dan memperbarui keadaan aksesibilitas. Accordion Perilaku tersebut sudah cukup untuk beberapa uji coba yang berguna:

Render awal menampilkan judul tetapi tidak menampilkan konten.

  1. Test the accordion like a user uses it
  2. Klik tombol trigger untuk menampilkan konten.
  3. Klik lagi untuk menyembunyikannya.
  4. Atribut aksesibilitas mencerminkan keadaan yang terlihat.

Poin terakhir seringkali dilupakan. Jika komponen Anda menggunakan atribut aria- atau struktur berdasarkan peran, pastikan mereka. aria-expanded, aria-controlsKomponen yang baik diuji seperti laporan bug yang tidak pernah Anda inginkan.

Pilih kueri berdasarkan niat.

React Testing Library memberikan Anda beberapa gaya kueri, tetapi mereka tidak dapat diganti-gantikan. Memilih yang salah membuat tes berisik atau menipu.

Jenis Kueri

Ketika Element DitemukanKetika Element Tidak DitemukanContoh PenggunaanKetika Element Ditemukan
getByMengembalikan elemen segeraMengeluarkan kesalahan segeraMenegaskan tombol atau judul harus sudah ada di layar
queryByMengembalikan elemen segeraMengembalikan nullMenegaskan konten disembunyikan tidak ada sebelum interaksi
findByTerpecah ketika elemen munculDitolak setelah menungguMenegaskan konten dimuat secara async muncul setelah fetch atau pembaruan tertunda

Model mental sederhana membantu:

  • Gunakan getBy untuk hal-hal yang harus sudah ada.
  • Gunakan untuk hal-hal yang harus tidak ada sebelumnya. queryBy Gunakan ketika tampilan UI berubah nanti.
  • Jika sebuah tes dimulai dengan findBy untuk segalanya, biasanya berarti penulis tidak yakin kapan komponen diperbarui. Ketidakpastian tersebut menjadi fluktuasi nanti.

Contoh accordion yang berguna findBy Ini adalah komponen representatif:

Dan ini adalah bentuk tes yang layak dipertahankan:

Apa yang hilang pun sangat penting. Tidak ada asseri terhadap keadaan internal. Tidak ada pengecekan bahwa

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

dipanggil. Tidak ada snapshot dari pohon yang di-render secara keseluruhan. Tes-tes tersebut akan menambah biaya perawatan, bukan kepercayaan.

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

Beberapa kebiasaan membuat tes komponen lebih kuat: setOpen __CAPGO_KEEP_0__

__CAPGO_KEEP_1__

  • Menggunakan kueri berdasarkan peran: Tombol, judul, dialog, peringatan, dan input biasanya dapat ditemukan dengan menggunakan peran.
  • Tetapkan setiap tes sempit: Satu perilaku yang dapat dilihat pengguna per tes menjaga kebacaan hasil tes.
  • Nama tes setelah hasilnya: “mengupdate aria-expanded ketika dibuka” jauh lebih berguna daripada “berfungsi dengan benar.”

Jika sebuah komponen sulit untuk diuji melalui DOM, seringkali itu menunjukkan masalah desain. Mungkin itu menyembunyikan keadaan di tempat yang salah. Mungkin itu kurang memiliki markup semantik. Tes yang baik seringkali mendorong tim menuju komponen yang lebih baik.

Menguji Hook-Hook Kustom dan Logika Aplikasi

Aplikasi React menyembunyikan banyak perilaku penting di luar komponen. Transisi keadaan hidup di hook. Validasi dan pengaturan format hidup di fungsi bantuan. Pengubahan data seringkali terjadi sebelum apa pun yang menampilkan. Jika Anda hanya menguji komponen yang dapat dilihat, Anda akan melewatkan sebagian besar code yang masih dapat mengganggu 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 adalah sebuah hook yang baik: useToggle Ujiannya harus tetap fokus pada kontrak publik:

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 berguna karena hook itu sendiri adalah unit. Anda tidak menguji bagian internal React. Anda memastikan perilaku eksternal hook.

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

Untuk tim produk yang membangun komponen UI atau primitif fitur yang dapat digunakan kembali, pola ini sangat penting. Hook seringkali menjadi interface yang digunakan bersamaan di antara aplikasi, sistem desain, atau alat bantu internal. Jika Anda merancang perilaku yang dapat digunakan kembali dengan tujuan komersial, sumber daya pada

hook untuk produk pembuat dapat membantu menggambarkan hook sebagai blok bangunan yang dapat digunakan kembali daripada hanya detail implementasi. Logika murni harus tetap murni dalam ujiannya

Tidak semua memerlukan

, jsdom,

,

export function formatDisplayName(firstName: string, lastName: string) {
  return `${firstName.trim()} ${lastName.trim()}`.trim();
}

,

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 di sini adalah kecepatan dan kejelasan. Ketika sebuah fungsi tidak memerlukan pohon yang di-render, jangan berikan padanya. Alat-alat React menambahkan beban tambahan. Pastikan tes logika bisnis kecil, cepat, dan dekat dengan fungsi yang mereka verifikasi.

Pembagian yang praktis bekerja dengan baik:

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

Tim seringkali melebih-lebihkan tes komponen dengan asertasi logika yang lebih rendah di dalam stack. Mengeluarkan logika itu memberikan dua manfaat. Tes komponen menjadi lebih bersih, dan tes logika menjadi lebih cepat.

Menguasai Teknik-teknik Lanjutan Mocking dan Async

Sistem React yang paling tidak dapat diandalkan rusak di dua tempat. Mereka rusak di batas 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 mengatributkan 46,5% dari ketidakstabilan pengujian ke masalah lingkungan atau terkait sumber daya seperti pengaturan waktu asinkron di analisis pengujian unit React ini. Di aplikasi React, hal itu berarti langsung ke transisi keadaan, rendering yang tertunda, UI yang dikemudikan oleh jaringan, dan tes yang menebak alih-alih menunggu secara deterministik.

Diagram perbandingan yang 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 mengaku bahwa palsuan Anda sendiri berfungsi.

Untuk komponen yang mengambil data akun, palsukan klien jaringan atau API modul. Jangan palsukan hook, komponen baris anak, spinner pengisian, 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
  • Platform API palsu yang tidak stabil: matchMedia, pengatur waktu, interface preload Electron, plugin Capacitor ketika tidak tersedia di jsdom
  • Hindari menggantikan internas Anda sendiri secara default: hook kustom, anak-anak sederhana, utilitas lokal

Jika sebuah 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 Kategori Jest adalah perpustakaan referensi yang praktis, terutama ketika mengontrak pengembang yang tahu React tapi belum mengerti mekanisme tes.

Tes asinkron gagal ketika waktu yang tidak jelas

Gagal asinkron biasanya berasal dari salah satu dari tiga kesalahan:

  1. Tes mengklaim terlalu awal.
  2. Tes menunggu dengan pengatur waktu acak.
  3. Komponen ini diperbarui lebih dari sekali, tetapi tes hanya menggambarkan satu transisi.

Bentuk tes async yang stabil biasanya 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 spesifik:

await waitFor(() => {
  expect(screen.getByRole('alert')).toBeInTheDocument();
});

Pilih findBy ketika penampilan satu elemen adalah acara yang Anda pedulikan. Pilih waitFor ketika kondisi lebih luas atau keadaan tidak dapat diungkapkan dengan satu kueri. Hindari setTimeout dalam tes kecuali Anda secara eksplisit menguji perilaku timer dan menggunakan timer palsu.

Ekosistem pengujian React juga mengharapkan Anda untuk menghormati act() semantik seputar pembaruan. Library Pengujian menangani banyak hal ini untuk Anda, tetapi jika Anda mengemudi keadaan secara manual atau maju timer, Anda masih perlu berpikir tentang kapan pembaruan memuaskan.

Pahami alat mocking mana yang harus Anda gunakan

Alat mocking yang berbeda menyelesaikan masalah yang berbeda:

AlatPenggunaan terbaikKesalahan umum
jest.fn()Panggilan balik palsu atau fungsi yang diinjeksikanMenggunakan itu untuk menggantikan modul utuh ketika callback sederhana sudah cukup
jest.spyOn()Mengamati atau mengganti satu metode pada objek atau modul yang sebenarnyaLupa untuk memulihkan implementasi asli
jest.mock()Mengganti ketergantungan modul pada batas imporMenggunakan mock besar secara default dan kehilangan perilaku yang bermakna

Contoh membantu:

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

Salah satu area yang maju 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 satu, 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 itu sama dengan kepercayaan. Tidak.

Anda bisa mencapai target koverasi dan masih melewatkan regresi yang penting. Suatu suite penuh asertasi dangkal, sketsa lebar, dan intern mock membuat penampilan keamanan sementara juga meningkatkan biaya perawatan.

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

Koverasi adalah peta, bukan tujuan

Laporan koverasi berguna ketika menjawab satu pertanyaan: jalur kritis mana yang belum dilindungi?

Mereka tidak berguna ketika mereka mendorong pengembang untuk menguji pembungkus sederhana, markup statis, atau file pass-through satu baris hanya untuk meningkatkan persentase. Gunakan coverage sebagai alat penemuan. Jika status autentikasi, aksi tagihan, flag fitur, atau prompt pembaruan tidak memiliki tes, itu adalah tanda. Jika komponen ikon presentasional tidak memiliki tes, biasanya bukan itu.

Pertanyaan review 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 mengaku detail implementasi atau mengulangi nilai tes lain.

Apa yang tidak perlu diuji unit

Banyak panduan React masih tidak menghabiskan waktu yang cukup pada pengabaian. Kesalahan itu penting karena pengujian berlebihan 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 ini:

  • Pengecekan status internal: Tidak perlu menguji secara langsung ketika Anda dapat menguji apakah panel terbuka. isOpen Behavior framework:
  • Tidak perlu menguji bahwa React memanggil efek. Uji hasil dari apa yang efek mengubah. Internals library pihak ketiga:
  • Uji integrasi dengan picker tanggal atau router, bukan logika rendering sendiri library. Satuan yang 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 __CAPGO_KEEP_0__ miliki. Tidak perlu menguji apa yang React, browser, atau library yang matang sudah miliki kecuali layer integrasi Anda mengubah kontrak.

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.

__CAPGO_KEEP_0__

Snapshots tidak sia-sia. Mereka hanya mudah digunakan secara tidak tepat.

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

Alternatif yang lebih baik biasanya ada:

  • Untuk rendering kondisional, pastikan kehadiran atau ketidakhadiran teks kunci.
  • Untuk perubahan visual, pastikan peran, label, atau atribut yang berpengaruh.
  • Untuk kesalahan dan fallback, pastikan pesan yang sebenarnya atau wilayah peringatan.

Jika tim Anda membutuhkan proses kualitas yang lebih luas di luar tes unit, teman yang solid adalah alur kualitas aplikasi yang menganggap tes, periksa rilis, dan perencanaan rollback sebagai satu sistem. Itu adalah perubahan mindset yang memperbaiki kualitas tes paling cepat. Berhenti bertanya berapa banyak tes Anda. Mulai bertanya mana saja kegagalan yang masih bisa mencapai pengguna.

Mengintegrasikan Tes ke Dalam Pipa CI/CD Berbasis Multi-Platform

Suatu suite tes yang hanya berjalan di laptop pengembang adalah saran, bukan kontrol.

Suatu suite menjadi operasional ketika setiap permintaan pull berjalan cek yang sama di lingkungan bersih dan menghalangi merge ketika cek tersebut gagal. Itu terdengar jelas, tapi banyak tim masih meninggalkan celah-celah kritis. Tes berjalan secara manual. Laporan coverase adalah opsional. Tugas pengemasan dan rilis dimulai sebelum tugas tes selesai. Itu adalah cara kecil perubahan UI masuk ke kegagalan rilis yang lebih besar.

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

Pull request harus memicu gate yang sama setiap kali.

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

  • Jalankan pada setiap pull request.
  • Instal dependensi dari lockfile.
  • Pakai perintah tes yang sama setiap kali.
  • Gagal cepat pada kegagalan tes.
  • Publikasikan artefak hanya setelah tes berhasil.

Ini adalah inti dari praktik pengembangan terus menerus untuk tim aplikasi.Bangun kepercayaan sebelum rilis, bukan setelah.

Alur kerja GitHub Actions yang sederhana sudah 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

This bukanlah hal yang menarik, 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: Aplikasi web code mungkin berjalan dengan baik secara lokal tetapi gagal ketika ada perubahan perilaku setelah pengemasan plugin, keadaan offline, atau kasus edge app lifecycle.
  • Aplikasi Electron: Komponen renderer mungkin bergantung pada API preload, pesan jendela, atau keadaan desktop yang tidak ada di pengujian browser biasa kecuali secara sengaja di mock.
  • Relai rilis bersama: Bundle yang buruk dapat mempengaruhi target yang lebih dari satu jika proses pengiriman tidak menggandakan 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

Pipelining yang lebih dewasa biasanya membagi tanggung jawab:

  1. Job uji coba: Uji unit dan hook yang cepat
  2. Job pembangunan: Pembangunan produksi hanya setelah tes berhasil
  3. Job paket: Capacitor sinkronisasi, pengemasan Electron, atau pengemasan artefak
  4. Job rilis: Publikasikan hanya 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 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 coba React Anda dapat berfungsi sebagai pintu keras pertama sebelum bundle web apa pun dipromosikan ke pengiriman staging atau produksi.

The aturan operasional adalah sederhana. Jangan biarkan infrastruktur rilis menggantikan tes yang lemah. Gunakan infrastruktur rilis setelah tes yang dapat diandalkan telah menyaring perubahan yang buruk.

Sebuah sistem tes yang dapat diandalkan mengubah perilaku tim. Para insinyur bergabung dengan lebih sedikit keraguan. Para pemeriksa fokus pada kasus sampingan daripada menjalankan dasar secara manual. Manajer rilis berhenti menganggap setiap deploy seperti sebuah taruhan. Itulah hasil dari melakukan unit testing React dengan baik.


Jika tim Anda mengirimkan React melalui Capacitor atau Electron, keamanan rilis bergantung pada lebih dari tes lokal hijau. Capgo memberikan tim cara yang terkendali untuk mempublikasikan pembaruan web yang ditandatangani, targetkan saluran peluncuran, dan kembali ke bundle yang buruk tanpa menunggu tinjauan toko, yang sesuai dengan alami di belakang pipeline CI yang sudah memerlukan melewati tes unit sebelum pengiriman.

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

Mulai Sekarang

Terbaru dari Blog Kami

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