Menjawab kebutuhan regression yang tahan flaky di Spring Boot
Tim yang mengelola aplikasi Spring Boot kehilangan kepercayaan pada regression suite ketika build sering merah bukan karena bug, tetapi akibat flaky test. Strategi yang berhasil memisahkan smoke dan regression suite, menjalankan regression dalam lingkungan yang konsisten via Testcontainers, dan mengukur flake rate akan langsung menjawab problem tersebut. Pendekatan ini memungkinkan tim mendeteksi regresi sebenarnya sekaligus mengidentifikasi dan memperbaiki test yang tidak stabil.
Artikel ini menunjukkan bagaimana merancang struktur suite, menyusun konfigurasi application-test.properties, menulis @SpringBootTest dengan data deterministik, serta menyusun pipeline CI/CD yang memverifikasi release tanpa mengorbankan kecepatan.
Membedakan smoke suite dan regression suite
Smoke suite adalah pengujian cepat yang memastikan komponen inti masih hidup selepas build. Regression suite mencakup skenario lebih luas. Untuk mendeteksi flaky test secara efektif, pisahkan keduanya dengan kriteria eksis:
- Smoke: fokus pada endpoint utama dan kondisi layanan yang paling sering berubah; jalankan di pre-merge atau PR build.
- Regression: mencakup alur bisnis lengkap dengan data kompleks, di-schedule secara nightly atau deployment candidate.
Regression suite berjalan lebih lama, sehingga harus dijalankan di environment yang sesuai agar tidak menghasilkan false positive. Prioritaskan test yang paling menerobos risiko produksi, dan gunakan tagging (@Tag("smoke"), @Tag("regression")) untuk seleksi suite di Gradle/Maven.
Menggunakan Testcontainers untuk menyamakan lingkungan pengetesan dengan produksi
Flaky test sering muncul karena perbedaan konfigurasi environment—database, broker, atau cache. Testcontainers menjalankan container Docker yang meniru dependency produksi dan bisa dikonfigurasi per suite.
Contoh application-test.properties minimal untuk memastikan Spring Boot mengarah ke kontainer Testcontainers:
spring.datasource.url=jdbc:tc:postgresql:14:///testdb?TC_INITSCRIPT=classpath:init.sql
spring.datasource.username=test
spring.datasource.password=test
spring.jpa.hibernate.ddl-auto=validate
logging.level.org.springframework.test.context=DEBUG
Gunakan jdbc:tc: untuk menghidupkan PostgreSQL saat test dijalankan, lalu biarkan Testcontainers mengelola lifecycle-nya. Pastikan konfigurasi ini juga digunakan pada regression suite agar hasilnya konsisten dengan produksi.
Praktik tambahan
- Shared container: Bila layanan Anda terhubung ke Redis, Kafka, atau Elasticsearch, buat container di
@Testcontainerspada kelas dasar dan gunakan kembali di semua test. - Cek readiness: Jangan anggap aplikasi sudah siap hanya karena kontainer hidup—tambahkan eksplisit health check atau tunda interaksi hingga container siap.
Membangun @SpringBootTest dengan data deterministik
Untuk memastikan regression suite tidak menghasilkan hasil acak, gunakan data deterministik yang sama di setiap run.
@SpringBootTest
@Testcontainers
@ActiveProfiles("test")
class OrderServiceRegressionTest {
@Container
static PostgreSQLContainer> postgres = new PostgreSQLContainer<>("postgres:14");
@DynamicPropertySource
static void overrideProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
@Autowired
OrderService orderService;
@Test
void prosesPesananDeterministik() {
// Pastikan data awal selalu sama
orderService.resetForRegressionTest();
var result = orderService.processOrder("SKU-123", 2);
assertThat(result.getStatus()).isEqualTo(OrderStatus.CONFIRMED);
}
}
Metode resetForRegressionTest() harus menyiapkan data awal yang konsisten—misalnya, membersihkan tabel dan memasukkan catalog statis. Hindari seed data yang diambil dari waktu nyata atau API eksternal agar tidak memperkenalkan nondeterminisme.
Mendeteksi dan memonitor flake rate
Flake rate adalah persentase test yang gagal secara sporadis. Tanpa monitoring, flaky test bisa tercecer dalam regression suite dan kembali menyebabkan ketidakpercayaan.
- Gunakan tool CI yang bisa menyimpan sejarah hasil test dan mengelompokkan berdasarkan nama test atau tag.
- Hitung flake rate dengan pola: (gagal sebelumnya lalu sukses di run berikutnya). Perluasan berupa pelaporan test yang gagal dua kali berturut-turut tanpa perubahan kode.
- Laporkan secara reguler: output grafis atau notifikasi ke tim devops bila flake rate suatu test melebihi ambang (misal 5%).
Debugging flaky test juga penting—ambil logs dan stack trace dari run yang gagal. Jangan abaikan peringatan timing atau race condition; biasanya menunjukkan bahwa test tidak menunggu readiness dependency.
Integrasi regression suite ke pipeline CI/CD
Langkah-langkah berikut membantu memastikan regression suite dan monitoring flake rate dijalankan sebelum release:
- Stage smoke: jalankan di PR build dengan tagging
smokeuntuk hasil cepat. - Stage regression: jalankan nightly atau di branch release candidate. Gunakan runner khusus dengan resource lebih besar agar Testcontainers tidak terkendala.
- Collect artifacts: simpan logs, test report, dan grafik flake rate setiap run regression;
- Threshold gating: Hentikan deployment bila flake rate di atas ambang atau ada test yang gagal lebih dari sekali tanpa perubahan kode.
- Promosi release: Setelah regression suite bersih, update artefak build (misal versi Docker image) lalu lanjutkan ke environment staging/production.
Integration example (CI):
stages:
- smoke
- regression
- deploy
smoke_tests:
script: ./gradlew test --tests *Smoke*
tags:
- docker
regression_tests:
script: ./gradlew test --tests *Regression* --info
when: manual
allow_failure: false
artifacts:
paths:
- build/test-results
analyze_flakes:
script: python scripts/flake_monitor.py build/test-results
dependencies:
- regression_tests
Script flake_monitor.py bisa membaca report XML untuk menghitung flake rate dan mengirim notifikasi bila ada tes yang bergagal-sukses bolak-balik.
Penutup
Strategi regression testing di Spring Boot harus mempertimbangkan pemisahan suite, determinisme data, lingkungan yang mirip produksi dengan Testcontainers, dan monitoring flaky test. Integrasi ke pipeline CI/CD memastikan build release tidak lolos dengan regression issue. Dengan pendekatan ini, tim dapat mendeteksi regresi substansial tanpa mengorbankan kecepatan delivery.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!