Episode ini membahas unit testing dengan Jest dan React Testing Library, integration dan E2E testing dengan Playwright atau Cypress, accessibility testing, serta static code analysis memakai ESLint dan type checking untuk menjaga kualitas.

Kode yang tidak diuji adalah bom waktu. Perubahan kecil bisa merusak fitur yang tidak pernah terbayangkan, dan bug baru muncul tanpa disadari sampai pengguna melapor. Testing mengubah proses itu: setiap regresi terdeteksi otomatis sebelum masuk production.
Episode 16 membahas unit testing dengan Jest dan React Testing Library, integration dan E2E testing dengan Playwright atau Cypress, accessibility testing, serta static analysis dengan ESLint dan type checking.
Jest adalah test runner paling populer untuk JavaScript, dipasangkan dengan React Testing Library untuk merender dan menguji komponen. Install keduanya:
npm install --save-dev jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom @swc/coreSetelah konfigurasi selesai, tes unit untuk komponen Counter di episode 7:
import { render, screen } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import Counter from "@/components/Counter"
test("tombol Tambah menaikkan hitungan", async () => {
render(<Counter />)
await userEvent.click(screen.getByRole("button", { name: "Tambah" }))
expect(screen.getByText("Hitungan: 1")).toBeInTheDocument()
})Tes di atas merender komponen, mengeklik tombol, dan memeriksa teks hasil. Mengakses elemen lewat getByRole alih-alih teks arbitrer memastikan komponen tetap dapat diakses screen reader.
Beberapa kebiasaan yang menjaga kualitas unit test: gunakan userEvent alih-alih fireEvent untuk simulasi yang realistis, mock fetch memakai MSW agar tes tidak bergantung pada jaringan, dan fokus pada perilaku yang terlihat pengguna, bukan detail implementasi. Jalankan unit test dalam mode watch saat development — setiap perubahan kode langsung memicu tes terkait, menutup loop umpan balik dengan cepat.
React Testing Library mendorong pengujian dari sudut pandang pengguna: cari elemen dari peran dan teks yang terlihat, bukan dari implementasi internal. Tes yang menulis detail implementasi mudah patah saat refactor, sedangkan tes perilaku tetap relevan selama fungsi komponen tidak berubah.
E2E (end-to-end) menguji alur lengkap di browser nyata: navigasi, login, pengisian form, sampai halaman tujuan. Playwright adalah pilihan modern yang mendukung banyak browser dan auto-wait:
import { test, expect } from "@playwright/test"
test("pengguna bisa login", async ({ page }) => {
await page.goto("/login")
await page.fill("#email", "user@example.com")
await page.fill("#password", "rahasia123")
await page.click("button[type=submit]")
await expect(page).toHaveURL(/\/dashboard/)
})page.fill dan page.click di atas mensimulasikan pengguna sungguhan. Assertion toHaveURL memastikan setelah login, pengguna tiba di dashboard.
Piramida testing: banyak unit test cepat, beberapa integration test, dan sedikit E2E. Unit test berjalan dalam milidetik dan memberi feedback instan; E2E berjalan lambat dan mahal, jadi dipakai untuk alur kritis seperti checkout dan autentikasi. Keseimbangan ini menjaga suite tetap cepat dan bermakna.
Pilih E2E untuk alur yang melibatkan banyak sistem: login, pembayaran, atau sinkronisasi data antar halaman. Untuk bagian lain, integration test yang merender komponen dengan data tiruan lebih cepat dan lebih stabil daripada E2E. Untuk project dengan banyak tim, pisahkan suite E2E ke workflow terpisah yang berjalan paralel di CI — Playwright mendukung sharding agar total waktu turun drastis.
E2E yang stabil butuh selektor yang tidak berubah saat layout berubah — gunakan atribut data-testid secara disiplin untuk elemen yang diuji.
Accessibility testing memastikan aplikasi bisa dipakai semua orang, termasuk pengguna screen reader. Otomatiskan sebanyak mungkin: jest-axe memeriksa masalah kontras dan atribut di unit test, sedangkan Playwright menyediakan pemeriksaan aksesibilitas di level halaman. Tapi otomatisasi tidak menggantikan pengujian manual dengan keyboard dan screen reader — beberapa masalah hanya terlihat saat benar-benar dinavigasi.
Mulailah dengan checklist dasar: semua elemen interaktif bisa diakses keyboard, kontras teks memenuhi standar WCAG, dan setiap gambar punya alt text. Perbaiki masalah yang ditemukan sebelum menambah fitur baru — aksesibilitas yang ditunda jarang pernah kembali dikerjakan.
Jadikan pengujian aksesibilitas bagian dari definition of done setiap fitur, bukan tugas terpisah di akhir sprint. Ini mencegah akumulasi utang aksesibilitas yang sulit dibereskan.
ESLint dan TypeScript menangkap kesalahan sebelum tes dijalankan. Atur agar keduanya berjalan di pipeline:
npm run lint
npx tsc --noEmitJalankan npm run lint dan npx tsc --noEmit di setiap push dan pull request. Gabungkan dengan husky dan lint-staged dari episode 3 agar masalah kualitas terdeteksi sebelum commit masuk riwayat.
Jadikan type checking bagian dari editor dengan menjalankan tsc dalam mode watch, atau andalkan integrasi TypeScript di VS Code. Error muncul saat mengetik, bukan menunggu CI — feedback yang jauh lebih cepat dan nyaman.
Perlakukan warning yang menumpuk seperti bug: jika lint berjalan dengan seratus warning, aturan praktisnya bersihkan dulu atau matikan dengan sengaja — jangan biarkan mengendap.
Inti yang harus dibawa pulang:
Di episode 17 selanjutnya kita akan membahas SEO dan content strategy — dasar SEO untuk Next.js, meta tags dan Open Graph dengan structured data, pembuatan sitemap dan konfigurasi robots, serta halaman berbasis konten dengan SEO yang mengutamakan performa. Visibilitas aplikasi kalian di mesin pencari akan naik kelas.