Spring Boot: Strategi Test & Deteksi Flaky di CI Pipeline membahas langkah konkret dalam mengunci regresi sekaligus mengungkap flaky test yang bisa merusak kepercayaan proses delivery. Di pembuka ini, kita langsung jelaskan bagaimana menggabungkan pengukuran coverage, profiling environment, dan deteksi flake agar pipeline CI tetap dapat dipercaya sebelum deploy.

Pada bagian berikut, saya uraikan pendekatan teknis dan konfigurasi yang bisa diikuti oleh tim Spring Boot: mulai dari struktur proyek, profil pengujian, pipeline Gradle/Maven, hingga monitoring hasil test dan tindakan rollback cepat ketika gating mendeteksi gangguan.

Pemahaman regresi dan flaky test dalam pipeline Spring Boot

Regresi muncul ketika perubahan kode memecah functionality yang sebelumnya sudah teruji, sementara flaky test hanya gagal secara acak tanpa perubahan kode nyata. Agar pipeline CI tahu perbedaan ini, bagi job testing menjadi dua lapis: component dan integration. Component test menjalankan service secara lokal, sedangkan integration test menyertakan komponen eksternal (database, message broker) dalam kondisi simulasi.

Menjawab kebutuhan ini, gunakan tag test (@Tag) untuk membedakan level pengujian. Pada setiap pipeline, jalankan component test secara rutin dan tarik integration test di stage berbeda agar biaya dan kestabilan tetap terkendali. Tandai test yang kerap gagal sebagai kandidat flaky, lalu cek ulang dengan rerun bergantian.

Identifikasi flake dan pengukuran coverage untuk regression control

Untuk mendeteksi flaky test, sediakan job khusus yang menjalankan ulang test sensitif beberapa kali. Misalnya, job test-rerun yang memanfaatkan plugin Maven Surefire/Failsafe atau task Gradle yang memanggil ulang test berdasarkan hasil kegagalan:

tasks.register("retryTests") {
    dependsOn("test")
    doLast {
        if (project.gradle.taskGraph.hasTask("test") && System.getenv("RETRY_ON_FAIL") == "true") {
            exec {
                commandLine("./gradlew", "test", "--tests", "com.example.*", "-Dtest.retry=1")
            }
        }
    }
}

Parallel job untuk rerun membantu memisah risiko flaky dari regresi sebenarnya. Bila rerun berhasil, tandai test tersebut untuk investigasi lebih lanjut: mungkin ada shared resource atau dependensi non-deterministik.

Untuk pengukuran coverage, integrasikan JaCoCo (Gradle) atau plugin Maven serupa. Tetapkan threshold minimal (regression gate) per modul. Coverage report yang diunggah ke CI bisa dipakai sebagai sinyal: apabila coverage turun dibanding baseline, pipeline bisa menolak merge:

  • Coverage per module: core, api, persistence, messaging.
  • Baseline history: bandingkan terhadap artefak release terakhir.
  • Threshold otomatis: misalnya 80% statement coverage untuk module core.

Pengukuran ini tidak hanya membantu regresi; ia juga memprioritaskan area dengan coverage tipis agar tidak menjadi titik lemah.

Arsitektur proyek Spring Boot dan profil environment yang berbeda

Contoh struktur proyek monorepo Spring Boot:

  1. module-core: domain logic, service.
  2. module-api: controller + DTO + security config.
  3. module-infra: repository + adapter ke database atau messaging.
  4. module-test-utils: test fixtures, container config.

Setiap modul memiliki profil Spring: test-component untuk component test (inisialisasi slice context) dan test-integration untuk integration test (DataSource nyata, Testcontainers). Penggunaan profil memudahkan pipeline memilih konfigurasi yang sesuai tanpa mengganti kode:

@ActiveProfiles("test-integration")
@SpringBootTest
class TransactionIntegrationTest {
    // konfigurasi Testcontainers untuk DB
}

Dengan pemisahan seperti ini, CI dapat menjalankan job component ringan setelah commit push dan job integration lebih berat setelah PR siap merge. Artinya, coverage dan flaky detection juga bisa diarahkan berbeda sesuai profil.

Konfigurasi pipeline CI dengan Gradle dan Maven

Berikut contoh pipeline ringkas (misalnya GitHub Actions atau GitLab CI) yang mencakup deteksi flaky dan gating otomatis:

jobs:
  component-test:
    steps:
      - run: ./gradlew clean test -Dspring.profiles.active=test-component -PcoverageThreshold
      - run: ./gradlew jacocoTestReport
      - run: ./scripts/check-coverage.sh
  integration-test:
    needs: component-test
    steps:
      - run: ./gradlew -Pci integrationTest -Dspring.profiles.active=test-integration
      - run: ./gradlew retryTests
  flaky-detection:
    needs: integration-test
    steps:
      - run: ./scripts/flake-gate.sh

Dalam tahap flake-detection, monitoring skrip menilai status rerun. Bila job rerun gagal, pipeline dikeluarkan dari deploy. Ini adalah bentuk automation test gating: pipeline secara otomatis menghentikan pergerakan bila ada indikasi instability.

Untuk Maven, serupa tapi gunakan mvn -Pcomponent-test test lalu plugin maven-surefire-plugin untuk retry. Pastikan job pipeline menangkap artefak report (JUnit, Surefire, JaCoCo). Penyimpanan artefak dibutuhkan untuk debugging ketika rerun gagal.

Monitoring hasil test dan respons rollback cepat

Monitoring mencakup agregasi log test, grafik failure trend, dan notifikasi. Gunakan dashboard CI (Jenkins Blue Ocean, GitLab Test Reports, dsb.) atau integrasi observabilitas (Grafana, Elastic). Data berikut membantu arahkan rollback:

  • Frekuensi fail: peningkatan dramatis menandai regresi, bukan flaky.
  • Rata-rata durasi integration test: lonjakan mencerminkan resource shortage.
  • Coverage delta: penurunan total coverage memicu alert.

Bila monitoring menunjukkan regression nyata setelah deploy (contoh: regression coverage menurun + test rerun gagal), lakukan rollback dengan cepat. Pastikan pipeline mencatat versi artefak pipeline sehingga rollback mengacu pada build yang sudah diverifikasi. Gunakan webhook ke sistem deployment untuk memicu rollback otomatis bila gate CI gagal di environment produksi.

Catatan debugging: ketika test rerun gagal, analisa output log, cek resource dependency (misalnya DB transaction timeout). Untuk flaky yang sulit direproduksi, tambahkan logging tambahan pada component atau gunakan Testcontainers yang deterministik.

Kesimpulan

Penerapan strategi terpadu—identifikasi flaky, pengukuran coverage sebagai guard terhadap regresi, pemisahan profil testing, pipeline gating otomatis, serta monitoring yang mengarah ke rollback cepat—membuat pipeline Spring Boot lebih stabil. Pilih tooling yang bisa dilapisi lintasan ini (JaCoCo, plugin retry Gradle/Maven, CI dashboard) sesuai kebutuhan organisasi, dan lakukan evaluasi berkala terhadap hasil coverage dan kegagalan test.