Lewati ke konten utama
menjadi.dev
Chapter 19.1 Testing Menengah

Testing: Mengapa Kode Butuh Diuji?

Filosofi testing dan perbedaan jenis test

Tujuan Pembelajaran

  • Memahami pentingnya testing
  • Bisa membedakan unit, integration, dan E2E test
  • Mengerti Test Pyramid

Analogi

Diagram

      Test Pyramid:
    /\
   /  \
  / E2E \     ← Sedikit, lambat, mahal
 /─────────\
/ Integration\  ← Sedang
/──────────────\
/    Unit Test   \ ← Banyak, cepat, murah
    

Unit test = banyak, cepat, murah. E2E = sedikit, lambat, tapi paling mirip user

Penjelasan Konsep

Bayangkan kamu membuat pesawat paper dan melemparkannya untuk melihat apakah terbang. Itu adalah ‘testing’ — memverifikasi bahwa apa yang kamu buat bekerja seperti yang diharapkan. Di software development, testing adalah proses memverifikasi bahwa kode kamu bekerja dengan benar.

Kenapa Testing Penting?

  1. Menangkap bug sebelum production: Lebih murah fix bug di development daripada di production
  2. Refactoring dengan percaya diri: Ubah kode tanpa takut merusak fitur yang sudah ada
  3. Dokumentasi hidup: Test menunjukkan cara menggunakan kode kamu
  4. Design yang lebih baik: Kode yang mudah di-test biasanya punya design yang lebih baik (loose coupling)
  5. Sleep better: Deploy di Jumat malam tanpa khawatir 😄

Tiga Jenis Test Utama

1. Unit Test — Menguji bagian kode terkecil (fungsi, class) secara isolasi. Cepat, murah, banyak.

Integration Test

Menguji bagaimana beberapa bagian bekerja sama. Database, API, service integration.

3. E2E (End-to-End) Test — Menguji aplikasi dari perspektif user. Browser automation, user flows. Lambat, mahal, tapi paling mirip real world.

Test Pyramid

Piramida ini menunjukkan berapa banyak test yang harus kamu tulis untuk setiap jenis:

  • Unit test (70%): Ratusan atau ribuan test — dieksekusi dalam detik
  • Integration test (20%): Puluhan test — dieksekusi dalam menit
  • E2E test (10%): Beberapa test — dieksekusi dalam puluhan menit

Analogi: Unit test seperti memeriksa setiap baut pesawat. Integration test seperti memeriksa apakah sayap terpasang dengan benar.

E2E test seperti terbangkan pesawatnya. Kamu periksa banyak baut, beberapa koneksi, dan terbangkan beberapa kali.

Testing Mindset

Tidak perlu 100% code coverage. Fokus pada:

  • Business logic yang penting
  • Edge cases (null, empty, error)
  • Bug yang pernah terjadi (regression test)
  • Happy path + 2-3 error paths

Inti yang Perlu Dipahami

Bagian ini berfokus pada memahami pentingnya testing., bisa membedakan unit, integration, dan E2E test., dan mengerti Test Pyramid. Jangan terburu-buru menghafal istilahnya. Lebih penting untuk memahami peran setiap konsep dan kapan konsep itu muncul dalam pekerjaan web development.

Saat membaca Testing, gunakan tujuan belajar sebagai penanda arah. Kalau kamu sudah bisa menjelaskan tujuan itu dengan kata-katamu sendiri, berarti fondasinya mulai terbentuk.

Cara Membayangkannya

Unit test = banyak, cepat, murah. E2E = sedikit, lambat, tapi paling mirip user. Analogi ini dipakai supaya konsep teknis tidak terasa melayang. Hubungkan setiap istilah dengan perannya: siapa yang meminta, siapa yang memproses, data apa yang berpindah, dan hasil apa yang diharapkan.

Kalau analoginya sudah terasa masuk akal, barulah lihat istilah teknisnya. Cara ini membuat materi lebih mudah dipahami daripada langsung menghafal definisi.

Saat Melihat Contoh Kode

Contoh kode pada chapter ini memakai bahasa typescript. Bacalah contoh kode sebagai ilustrasi alur, bukan sebagai bagian yang harus langsung dihafal. describe() mengelompokkan test. it() mendefinisikan satu test case. expect() membuat assertion. Edge case: kode invalid dan price <= 0.

Perhatikan nama fungsi, urutan langkah, dan data yang berpindah. Biasanya tiga hal itu sudah cukup untuk memahami hubungan antara teori dan praktik.

Konteks dalam Perjalanan Belajar

Setiap konsep di platform ini dipilih karena dipakai di industri. Fokus pada pemahaman, bukan hafalan.

Kamu sudah di bagian lanjutan. Mulai pikirkan bagaimana konsep ini dipakai di dunia kerja — bukan hanya untuk belajar, tapi untuk membangun produk nyata.

Gunakan pertanyaan reflektif dan prompt AI di akhir chapter sebagai latihan aktif. Membaca saja tidak cukup — kamu perlu menjelaskan ulang dengan kata-katamu sendiri.

Contoh Kode

typescript
// Fungsi yang akan kita test
export function calculateDiscount(price: number, code: string): number {
  if (price <= 0) throw new Error('Price must be positive');
  
  const discounts: Record<string, number> = {
    'SAVE10': 0.10,
    'SAVE20': 0.20,
    'HALF': 0.50,
  };
  
  const rate = discounts[code] ?? 0;
  return price * (1 - rate);
}

// Unit test dengan Vitest (syntax mirip Jest)
import { describe, it, expect } from 'vitest';

describe('calculateDiscount', () => {
  // Happy path
  it('applies 10% discount', () => {
    expect(calculateDiscount(100, 'SAVE10')).toBe(90);
  });
  
  it('applies 20% discount', () => {
    expect(calculateDiscount(100, 'SAVE20')).toBe(80);
  });
  
  // Edge case
  it('returns original price for invalid code', () => {
    expect(calculateDiscount(100, 'INVALID')).toBe(100);
  });
  
  it('throws error for zero price', () => {
    expect(() => calculateDiscount(0, 'SAVE10')).toThrow('Price must be positive');
  });
  
  it('handles half price', () => {
    expect(calculateDiscount(200, 'HALF')).toBe(100);
  });
});

Penjelasan Kode

describe() mengelompokkan test. it() mendefinisikan satu test case. expect() membuat assertion. Edge case: kode invalid dan price <= 0.

Prompt AI

Tulis unit test untuk fungsi validasi email. Test: format valid, format invalid, empty string, dan domain yang tidak umum.

Pertanyaan Reflektif

Tanpa test, refactor adalah perjudian. Dengan test, refactor adalah investasi. Kamu lebih percaya diri yang mana?