Flaky API test menyebabkan hasil uji bervariasi tanpa ada perubahan logis pada kode, sehingga sulit membedakan antara bug nyata dan kebisingan. Untuk mencegah regresi yang tidak terdeteksi, Anda perlu mengukur flakiness sejak pipeline CI, mulai dari pemilahan jenis test hingga respon sistem terhadap metrik yang berubah.

Dalam artikel ini, kami langsung membahas cara membangun strategi verifikasi API di Laravel yang mengukur flaky tests dengan pendekatan praktis—mulai dari jenis test, deteksi flake, konfigurasi PHPUnit/Pest, hingga visualisasi tren regresi dan tindak lanjut pasca metrik.

1. Memilah Test API: Unit, Integrasi, Kontrak

Pertama, pisahkan test berdasarkan cakupan agar flakiness bisa dilokalisasi. Test unit hanya mengecek logika lokal; integrasi mengecek bundling service; sedangkan kontrak (contract) memastikan API tetap memenuhi spesifikasi konsumen.

  • Unit test: isolasi dependency dengan mock/fake. Flake di layer ini biasanya disebabkan oleh state global atau parallel test yang saling bersinggungan.
  • Integrasi test: berinteraksi dengan database, queue, atau HTTP. Pastikan setiap test membersihkan state (misalnya menggunakan database transactions atau refreshDatabase trait) sehingga proses yang dijalankan bisa direproduksi.
  • Contract test: validasi publish-subscribe API atau schema response. Gunakan fixture konsisten dan track versi kontrak supaya jika service downstream berubah, flake teridentifikasi sebagai perubahan valid instead of noise.

Dengan pemilahan ini, Anda bisa menyaring metrik flaky per kategori dan fokus di area yang paling berisiko.

2. Mekanisme Deteksi Flaky

Setelah pembagian, siapkan mekanisme deteksi yang terukur.

Retry Count di CI

Jalankan test yang sering gagal ulang beberapa kali (misalnya 2-3 kali) sebelum menandai sebagai kegagalan. Ini bukan berarti mengabaikan kesalahan, tetapi menandai test yang konsisten gagal dengan pola tertentu.

Simpan hasil retry (gagal, berhasil) sebagai data. Bila suatu test melewati retry tapi kemudian lulus, pertimbangkan untuk mencatatnya sebagai flaky observation dan tambahkan ke daftar pengamatan.

Histogram Durasi

Flaky sering kali berhubungan dengan latency. Catat waktu eksekusi tiap test API dan simpan ke histogram (misalnya Prometheus histogram, atau grafana Loki). Jika distribusi waktu melebar atau ada spike, itu indikasi ketergantungan external yang tidak stabil.

Isolasi dan Dependensi Eksternal

Pastikan test API dijalankan dengan lingkungan yang terkontrol: gunakan database test khusus, mocking HTTP request external, dan clearing cache/shared state setelah tiap test. Gunakan trait seperti RefreshDatabase atau DatabaseTransactions dari Laravel.

Debugging tip: bila test gagal hanya di CI, cek apakah cache/queue driver menggunakan Redis/Queue shared. Flake sering muncul bila worker sebelumnya belum selesai atau queue tidak dibersihkan.

3. Konfigurasi PHPUnit/Pest untuk Metrik Flake

Gunakan tag/group di PHPUnit/Pest untuk memfilter test yang ingin dimonitor flake-nya. Misalnya:

<testsuites>
  <testsuite name="api-flaky">
    <directory suffix="Test.php">./tests/Feature/API</directory>
  </testsuite>
</testsuites>
<group name="flaky-api"/>

Tambahkan flag environment dalam phpunit.xml agar CI bisa menyalakan mode verbose logging khusus test ini. Contoh:

<php>
  <env name="FLAKY_API_MONITOR" value="1"/>
</php>

Di sisi Pest/lumen, gunakan tag @group flaky-api dan runner CLI vendor/bin/pest --group=flaky-api untuk hanya menjalankan subset tersebut.

4. Memisahkan Environment dengan Middleware atau Feature Flag

Bisa jadi flaky disebabkan karena test berjalan terhadap service yang sama dengan production. Terapkan middleware atau feature flag untuk memastikan test berjalan di environment yang terisolasi.

Contoh middleware sederhana:

namespace App\Http\Middleware;
use Closure;

class EnsureTestEnvironment
{
    public function handle($request, Closure $next)
    {
        if (!app()->environment('testing') && !config('features.testing_mode')) {
            abort(403, 'API testing mode harus diaktifkan.');
        }
        return $next($request);
    }
}

Aktifkan feature flag melalui config/feature.php yang bisa diubah oleh CI sebelum test. Ini mencegah test API memengaruhi data produksi sekaligus memaksa pengujian hanya bisa dijalankan saat flag aktif.

5. Visualisasi Tren Regresi di CI

Setiap build CI harus mengekspor metrik flake (retry count, failure ratio, durasi) ke storage yang bisa divisualisasikan. Misalnya:

  • Simpan hasil statistika ke path JSON di workspace (build/metrics/flaky-api.json).
  • Upload ke artifact atau push ke grafana Loki/Prometheus via exporter.
  • Gunakan dashboard yang memplot tren: jumlah test yang retry, persentase gagal, serta durasi rata-rata.

CI script bisa menambahkan langkah seperti php artisan test:flaky-metrics yang mencatat data ke database internal atau push ke CSV. Jika tren menanjak, CI bisa memecah failure berulang dan menandai test tertentu untuk review developer.

6. Menindaklanjuti Hasil Metrik

Setelah ada data, penting untuk menjadikan metrik sebagai bagian dari workflow:

  • Review berkala: tambahkan card di backlog untuk test dengan flake tinggi. Diskusikan apakah test harus disederhanakan, or if dependencies need stabilization.
  • Perbaiki isolation: cek apakah database/queue terkait shared state. Pertimbangkan menggunakan fake queue driver untuk test atau queue dedicated khusus test.
  • Catat di PR: jika test baru menambah flake, minta pembuat PR memberikan insight kenapa flake muncul (contoh: eksternal API lambda). Ini memaksa tim memperhatikan flake sebelum merge.

Gunakan metrik sebagai gate: build failed jika flake ratio naik di atas ambang tertentu, sehingga regression tidak masuk ke production tanpa analisis lebih lanjut.

Kesimpulan

Mengukur flaky API test di Laravel berarti menggabungkan beberapa layer: klasifikasi test, deteksi stateless, konfigurasi runner, isolasi environment, serta visualisasi dan tindak lanjut metrik. Pendekatan ini bukan hanya menciptakan pipeline yang lebih stabil, tetapi juga memberi pemahaman berbasis data agar tim bisa memutuskan apakah kegagalan berasal dari produksi atau noise.