Memprediksi masa depan keandalan software seperti cuaca — dengan model matematis yang dibangun dari data kegagalan nyata.
Tanpa model, kita tidak bisa menjawab pertanyaan kritis seperti: "Kapan software ini cukup andal untuk dirilis?" atau "Berapa banyak bug yang masih tersembunyi?"
Model keandalan seperti BMKG yang meramalkan cuaca.
BMKG tidak melihat masa depan secara langsung — mereka menggunakan data suhu, tekanan udara, kelembaban hari-hari sebelumnya, lalu memasukkannya ke model matematis untuk memperkirakan cuaca besok. Model keandalan bekerja persis sama: kita gunakan data kegagalan masa lalu untuk memprediksi kapan sistem akan gagal berikutnya, atau berapa banyak bug yang masih ada.
Kapan software siap dirilis? Model membantu menentukan apakah jumlah bug yang tersisa sudah di bawah ambang batas yang dapat diterima.
Berapa banyak tester yang masih dibutuhkan? Berapa lama fase pengujian harus berlangsung? Model memberikan estimasi berbasis data.
Mengetahui berapa bug yang masih tersisa membantu menghitung biaya perbaikan yang diperlukan sebelum rilis.
Apakah proses pengujian kita efektif? Model menunjukkan tren — apakah keandalan meningkat sesuai harapan atau tidak.
Memprediksi keandalan sebelum software selesai dibuat, berdasarkan karakteristik kode (kompleksitas, ukuran, dll). Seperti memperkirakan seberapa kuat sebuah jembatan berdasarkan blueprint-nya — sebelum dibangun.
Mengestimasi keandalan saat pengujian berlangsung, berdasarkan data kegagalan yang sudah terjadi. Seperti memperkirakan apakah mobil sudah layak jalan berdasarkan hasil uji coba di sirkuit test.
Dalam sesi ini kita fokus pada Software Reliability Growth Models (SRGM) — model estimasi yang paling banyak digunakan di industri.
SRGM didasarkan pada ide sederhana: setiap kali bug ditemukan dan diperbaiki, reliability software meningkat. Proses pengujian adalah proses "pertumbuhan keandalan".
SRGM seperti proses belajar mahasiswa sebelum ujian. Semakin banyak soal latihan dikerjakan (= pengujian), semakin banyak kelemahan ditemukan (= bug), dan setelah diperbaiki (= belajar dari kesalahan), kemampuan mahasiswa meningkat (= reliability tumbuh). Grafik nilainya pun naik secara bertahap, mirip dengan kurva SRGM.
Input Data yang Dibutuhkan:
Output yang Diperoleh:
Model paling sederhana dan tertua. Analoginya seperti setoples kelereng — setiap kali Anda menemukan dan mengambil satu kelereng (= bug diperbaiki), jumlah kelereng berkurang, dan probabilitas menemukan kelereng berikutnya juga berkurang.
Model ini menggunakan Non-Homogeneous Poisson Process (NHPP) — artinya jumlah kegagalan per satuan waktu berubah seiring berjalannya pengujian (tidak konstan). Analoginya seperti kurva belajar — paling banyak hal baru dipelajari di awal, lalu semakin lama semakin sedikit.
John Musa menyadari bahwa waktu kalender (jam/hari) bisa menipu — 8 jam pengujian oleh 1 tester tidak sama dengan 1 jam pengujian paralel oleh 8 tester. Solusinya: gunakan execution time (waktu CPU aktif menjalankan kode). Analoginya: mengukur bukan berapa jam kamu belajar, tapi berapa soal yang kamu kerjakan.
Model ini berbeda: ia mengasumsikan jumlah bug tidak terbatas (infinite). Kenapa? Karena setiap kali software di-patch, ada kemungkinan bug baru masuk. Analoginya: seperti membersihkan rumah yang terus-menerus dikotori — selalu ada kotoran baru, tapi prosesnya tetap bisa dimodel secara logaritmik.
| Model | Asumsi Jumlah Bug | Jenis Data | Cocok Untuk | Kompleksitas |
|---|---|---|---|---|
| Jelinski-Moranda | Finite, homogen | TBF | Sistem kecil, fase awal belajar SRGM | ⭐ Rendah |
| Goel-Okumoto | Finite, inhomogen | Failure count | Kebanyakan software komersial | ⭐⭐ Sedang |
| Musa Basic | Finite | Execution time | Software embedded, sistem kritis | ⭐⭐ Sedang |
| Musa-Okumoto Log | Infinite | Execution time | Software besar yang terus di-maintain | ⭐⭐⭐ Tinggi |
Penting: Tidak ada model yang "terbaik" secara universal. Pilih model berdasarkan karakteristik data dan sistem Anda, lalu validasi dengan goodness-of-fit test (misalnya Kolmogorov-Smirnov atau Chi-Square).
Data kumulatif kegagalan selama pengujian: t=1 bulan → 5 failure, t=2 → 9, t=3 → 12, t=4 → 14, t=5 → 15. Gunakan model Goel-Okumoto μ(t) = a(1−e−bt).
Plot data dan amati polanya. Kumulatif failure: (1,5), (2,9), (3,12), (4,14), (5,15). Pola ini menunjukkan kurva yang mendatar — cocok untuk model eksponensial G-O.
Estimasi parameter a dan b secara intuitif. Pada t=5, kurva mulai mendatar mendekati 15. Jadi kita perkirakan a ≈ 16 (total bug yang diperkirakan). Dari data awal, pertumbuhan cepat → b ≈ 0.6.
Hitung μ(t) dengan a=16, b=0.6:
μ(1) = 16×(1−e−0.6) = 16×0.451 = 7.2 (aktual: 5)
μ(3) = 16×(1−e−1.8) = 16×0.835 = 13.4 (aktual: 12)
μ(5) = 16×(1−e−3.0) = 16×0.950 = 15.2 (aktual: 15)
Prediksi bug yang tersisa:
Jumlah bug tersisa ≈ a − μ(5) = 16 − 15.2 = ~1 bug lagi
Ini berarti software hampir siap dirilis!
Failure Intensity saat ini:
λ(5) = a·b·e−b×5 = 16 × 0.6 × e−3 = 9.6 × 0.0498 = 0.478 failure/bulan
Sangat kecil — artinya sistem sudah sangat andal!
✅ Kesimpulan: Berdasarkan model G-O, software ini memiliki ~1 bug tersisa dan failure intensity sudah sangat rendah (0.478/bulan). Layak untuk dipertimbangkan rilis dengan monitoring yang ketat.
# ================================================================ # S11409 - Sesi 3: Fitting Software Reliability Growth Model (SRGM) # Model: Goel-Okumoto (G-O) NHPP # Dosen: Riadi Marta Dinata, S.Ti., M.Kom. | ISTN Jakarta # ================================================================ import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit from scipy.stats import kstest import warnings warnings.filterwarnings('ignore') # ── DATA KEGAGALAN KUMULATIF (bulan, cumulative failures) ── t_data = np.array([1, 2, 3, 4, 5, 6, 7, 8]) m_data = np.array([5, 9, 12, 14, 15, 15.5, 15.8, 16]) # kumulatif # ── DEFINISI MODEL ── def goel_okumoto(t, a, b): """Goel-Okumoto Mean Value Function: μ(t) = a(1 - e^(-bt))""" return a * (1 - np.exp(-b * t)) def failure_intensity_go(t, a, b): """Failure Intensity: λ(t) = ab·e^(-bt)""" return a * b * np.exp(-b * t) def jelinski_moranda_rate(i, phi, N0): """J-M Failure Rate: λ_i = φ(N0 - (i-1))""" return phi * (N0 - (i - 1)) # ── FITTING PARAMETER MODEL G-O ── print("="*55) print(" FITTING GOEL-OKUMOTO MODEL") print("="*55) popt, pcov = curve_fit(goel_okumoto, t_data, m_data, p0=[20, 0.5], # initial guess: a=20, b=0.5 bounds=([0, 0], [np.inf, np.inf]), maxfev=10000) a_fit, b_fit = popt perr = np.sqrt(np.diag(pcov)) print(f"Parameter a (total bugs): {a_fit:.4f} ± {perr[0]:.4f}") print(f"Parameter b (detect rate): {b_fit:.4f} ± {perr[1]:.4f}") # ── PREDIKSI & EVALUASI ── t_pred = np.linspace(0, 12, 200) # prediksi hingga bulan 12 m_pred = goel_okumoto(t_pred, a_fit, b_fit) lam_pred = failure_intensity_go(t_pred, a_fit, b_fit) # Hitung residuals dan goodness-of-fit m_fitted = goel_okumoto(t_data, a_fit, b_fit) residuals = m_data - m_fitted ss_res = np.sum(residuals**2) ss_tot = np.sum((m_data - np.mean(m_data))**2) r_squared = 1 - (ss_res / ss_tot) print(f"\nGoodness of Fit R² : {r_squared:.6f}") print(f"RMSE : {np.sqrt(ss_res/len(m_data)):.4f}") # ── PREDIKSI BUG TERSISA ── bugs_found = m_data[-1] # sampai saat ini bugs_remaining = a_fit - bugs_found t_target = 9 # target bulan ke-9 m_at_target = goel_okumoto(t_target, a_fit, b_fit) lam_at_target = failure_intensity_go(t_target, a_fit, b_fit) print(f"\n--- PREDIKSI ---") print(f"Total bug diperkirakan : {a_fit:.1f}") print(f"Bug ditemukan s/d bulan 8 : {bugs_found:.1f}") print(f"Bug tersisa (perkiraan) : {bugs_remaining:.2f}") print(f"Failure intensity bulan 9 : {lam_at_target:.4f}/bulan") # ── KAPAN LAYAK RILIS? ── target_intensity = 0.1 # target failure rate yang bisa diterima # Cari t ketika λ(t) ≤ target: t = -ln(target / (a*b)) / b if a_fit * b_fit > target_intensity: t_release = -np.log(target_intensity / (a_fit * b_fit)) / b_fit print(f"Estimasi waktu siap rilis : Bulan ke-{t_release:.1f}") print(f" (saat failure intensity ≤ {target_intensity}/bulan)") # ── VISUALISASI ── fig, axes = plt.subplots(1, 3, figsize=(15, 5)) fig.suptitle('Software Reliability Growth Model - Goel-Okumoto', fontsize=14, fontweight='bold') # Plot 1: Cumulative Failures (Data vs Model) axes[0].scatter(t_data, m_data, color='#C8102E', s=80, zorder=5, label='Data Aktual') axes[0].plot(t_pred, m_pred, color='#38BDF8', lw=2, label=f'G-O Fit (a={a_fit:.1f}, b={b_fit:.2f})') axes[0].axhline(a_fit, color='#D4A017', linestyle='--', label=f'Total bugs ≈ {a_fit:.1f}') axes[0].set_xlabel('Waktu Pengujian (bulan)') axes[0].set_ylabel('Kumulatif Kegagalan') axes[0].set_title('Cumulative Failure vs G-O Model') axes[0].legend(fontsize=8); axes[0].grid(alpha=0.3) # Plot 2: Failure Intensity (menurun = reliability meningkat) axes[1].plot(t_pred, lam_pred, color='#22C55E', lw=2) axes[1].axhline(target_intensity, color='#F97316', linestyle='--', label=f'Target λ = {target_intensity}') axes[1].fill_between(t_pred, lam_pred, target_intensity, where=(lam_pred <= target_intensity), alpha=0.2, color='#22C55E', label='Zona Aman Rilis') axes[1].set_xlabel('Waktu Pengujian (bulan)') axes[1].set_ylabel('Failure Intensity λ(t)') axes[1].set_title('Failure Intensity (Reliability Growth)') axes[1].legend(fontsize=8); axes[1].grid(alpha=0.3) # Plot 3: Residuals axes[2].bar(t_data, residuals, color=['#22C55E' if r >= 0 else '#C8102E' for r in residuals], alpha=0.8) axes[2].axhline(0, color='white', lw=1) axes[2].set_xlabel('Waktu Pengujian (bulan)') axes[2].set_ylabel('Residual (Aktual - Prediksi)') axes[2].set_title(f'Residuals (R² = {r_squared:.4f})') axes[2].grid(alpha=0.3) plt.tight_layout() plt.savefig('srgm_goel_okumoto.png', dpi=150, bbox_inches='tight') print("\n✅ Grafik disimpan: srgm_goel_okumoto.png")
Instalasi dependensi: pip install numpy matplotlib scipy — Jalankan: python srgm_fitting.py
Parameter a (total bugs):
Jumlah bug total yang diperkirakan ada dalam software. Jika a=16.2 dan sudah 16 yang ditemukan, tersisa hanya 0.2 — sistem hampir bersih!
Parameter b (detection rate):
Seberapa cepat bug ditemukan. b besar = bug cepat ditemukan di awal. b kecil = proses penemuan bug lambat/merata.
R² mendekati 1:
R² > 0.99 artinya model sangat cocok dengan data. Jika R² rendah, coba model SRGM yang berbeda.
Zona Aman Rilis:
Ketika failure intensity sudah di bawah target (misal 0.1/bulan), software dianggap cukup andal untuk dirilis.
Jelaskan dengan analogi sederhana mengapa model SRGM dibutuhkan dalam pengembangan software. Apa yang terjadi jika tim tidak menggunakan model dan hanya mengandalkan intuisi untuk menentukan waktu rilis?
Gunakan model Jelinski-Moranda: sebuah software diperkirakan memiliki N₀=20 bug, dengan φ=0.01 per jam. Hitunglah failure rate setelah: (a) 0 bug diperbaiki, (b) 5 bug diperbaiki, (c) 10 bug diperbaiki. Apa tren yang Anda lihat?
Gunakan model G-O dengan a=25 dan b=0.4. Hitunglah: (a) μ(t) untuk t = 1, 2, 3, 5, 10 bulan, (b) Failure intensity λ(t) untuk t yang sama, (c) Kapan jumlah bug yang diharapkan mencapai 90% dari total (a)?
Modifikasi kode Python di atas untuk: (a) membandingkan model G-O dengan Jelinski-Moranda pada dataset yang sama, (b) menampilkan tabel perbandingan R² kedua model, (c) menentukan model mana yang lebih baik berdasarkan R² dan RMSE.
Mengapa model Musa menggunakan "execution time" bukan "calendar time"? Berikan skenario nyata di mana penggunaan calendar time akan memberikan hasil yang menyesatkan jika digunakan dalam SRGM.
SRGM memodelkan pertumbuhan keandalan seiring bertambahnya bug yang ditemukan dan diperbaiki
Goel-Okumoto μ(t) = a(1−e⁻ᵇᵗ) adalah model paling populer dengan 2 parameter (a=total bugs, b=detection rate)
Failure intensity λ(t) turun artinya reliability meningkat — grafik ini yang ditunjukkan kepada manajemen
scipy.optimize.curve_fit adalah tool Python untuk meng-fit model ke data nyata secara otomatis
R² mendekati 1 menunjukkan model cocok dengan data — jika rendah, coba model SRGM berbeda
Tidak ada model universal terbaik — pilih berdasarkan karakteristik data dan validasi dengan uji statistik