TDD & CI/CD Automation — Testing

Test-Driven Development (TDD) TDD adalah metodologi pengembangan di mana kita menulis test sebelum menulis kode implementasi. Prosesnya mengikuti siklus…

Test-Driven Development (TDD)

TDD adalah metodologi pengembangan di mana kita menulis test sebelum menulis kode implementasi. Prosesnya mengikuti siklus Red-Green-Refactor:

Siklus Red-Green-Refactor

RED GREEN REFACTOR tulis kode bersihkan test baru
Siklus TDD berulang: tulis test gagal, buat hijau, bersihkan, ulangi.

Refactor Itu Langkah Eksplisit, Bukan Opsional

Setelah fase Green, sebelum masuk ke Red berikutnya, ambil waktu khusus untuk refactor:

Syaratnya satu: setelah refactor, semua test harus tetap hijau. Kalau ada test yang patah, kamu mengubah behaviour — itu bukan refactor, itu bug baru.

Contoh TDD

// LANGKAH 1 (Red): Tulis test dulu
import { describe, it, expect } from "vitest";
import { hitungDiskon } from "./diskon";

describe("hitungDiskon", () => {
  it("memberikan diskon 10% untuk belanja di atas 100rb", () => {
    expect(hitungDiskon(200000)).toBe(180000);
  });

  it("tidak ada diskon untuk belanja di bawah 100rb", () => {
    expect(hitungDiskon(50000)).toBe(50000);
  });

  it("mengembalikan 0 untuk nilai negatif", () => {
    expect(hitungDiskon(-10000)).toBe(0);
  });
});
// LANGKAH 2 (Green): Implementasi minimum
export function hitungDiskon(total) {
  if (total < 0) return 0;
  if (total > 100000) return total * 0.9;
  return total;
}
// LANGKAH 3 (Refactor): Perbaiki kode
const BATAS_DISKON = 100000;
const PERSENTASE_DISKON = 0.1;

export function hitungDiskon(total) {
  if (total < 0) return 0;
  if (total > BATAS_DISKON) {
    return total * (1 - PERSENTASE_DISKON);
  }
  return total;
}

Kapan Menggunakan TDD?

CI/CD — Continuous Integration & Delivery

CI (Continuous Integration) berarti menjalankan test otomatis setiap kali ada push atau pull request. CD (Continuous Delivery) berarti deploy otomatis setelah test lulus.

GitHub Actions untuk JavaScript

# .github/workflows/test.yml
name: Test

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test-js:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "npm"
      - run: npm ci
      - run: npm test -- --run

GitHub Actions untuk Laravel

  test-php:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8
        env:
          MYSQL_DATABASE: testing
          MYSQL_ROOT_PASSWORD: password
        ports:
          - 3306:3306
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: "8.3"
      - run: composer install --no-interaction
      - run: cp .env.example .env
      - run: php artisan key:generate
      - run: php artisan test

Test Coverage

Test coverage mengukur persentase kode yang dijalankan oleh test:

# Vitest coverage
npx vitest --coverage

# PHPUnit coverage
php artisan test --coverage

Metrik Coverage

Target realistis: 80% coverage untuk kode bisnis utama. 100% coverage bukan tujuan — fokus pada kualitas test, bukan kuantitas.

Tips CI/CD

Yang akan kamu pelajari