Contract Testing: Jaga API Microservice Tetap Kompatibel
Mengapa Contract Testing Penting
Dalam arsitektur microservice, layanan berkomunikasi melalui API. Perubahan pada satu layanan bisa tanpa sengaja merusak layanan lain dan memicu kegagalan runtime yang berbiaya tinggi. Contract testing menyelesaikan masalah ini dengan memverifikasi bahwa provider dan consumer sepakat pada bentuk request dan response sebelum perubahan di-deploy.
Artikel ini membahas konsep inti, alat populer, dan langkah praktis untuk mengintegrasikan contract testing ke dalam pipeline CI/CD kamu.
Daftar Isi
- Apa Itu Contract?
- Manfaat Contract Testing
- Alat Contract Testing Populer
- Menerapkan Contract Test
- Jika Sudah Punya OpenAPI/Swagger
- Integrasi CI/CD
- Best Practices
- Kesalahan Umum & Cara Menghindarinya
- Kesimpulan
- Referensi
Apa Itu Contract?
Contract adalah deskripsi interaksi API yang dapat dibaca mesin. Contract bisa diekspresikan dalam:
- Spesifikasi OpenAPI/Swagger (JSON atau YAML)
- DSL Pact (JSON atau YAML) untuk contract yang digerakkan consumer
- Skema GraphQL introspection
Contract disimpan di repositori bersama dan dikelola dengan version control bersama kode layanan.
Manfaat Contract Testing
| Manfaat | Penjelasan |
|---|---|
| Deteksi Dini | Kegagalan contract terdeteksi saat unit testing, bukan di produksi. |
| Pengembangan Terpisah | Consumer dapat membuat stub provider dari contract, sehingga pengembangan paralel lebih mudah. |
| Jaring Pengaman Refactoring | Mengubah bentuk response memicu kegagalan contract, mencegah perubahan yang merusak secara diam-diam. |
| Dokumentasi | Contract berfungsi sebagai dokumentasi API yang selalu up-to-date untuk manusia dan mesin. |
Alat Contract Testing Populer
| Alat | Dukungan Bahasa | Consumer‑Driven? | Catatan |
|---|---|---|---|
| Pact | JS, Java, Ruby, Go, .NET, dll. | ✅ | Ekosistem matang dan mendukung broker untuk versioning. |
| OpenAPI Validator | JS, Python, Java | ❌ (fokus provider) | Cocok bila API didefinisikan terlebih dahulu. |
| Dredd | Node.js | ❌ (spec-driven) | Memvalidasi deskripsi API langsung ke service yang berjalan. |
| Spring Cloud Contract | Java/Kotlin | ✅ | Menghasilkan stub dan tes dari contract. |
Menerapkan Contract Test (Contoh dengan Pact)
1. Instal Dependensi
npm install --save-dev @pact-foundation/pact @pact-foundation/pact-node
2. Definisikan Tes Consumer
// consumer.test.js
import { Pact } from '@pact-foundation/pact';
import path from 'path';
import axios from 'axios';
const provider = new Pact({
consumer: 'OrderService',
provider: 'InventoryService',
port: 1234,
log: path.resolve(process.cwd(), 'logs', 'pact.log'),
dir: path.resolve(process.cwd(), 'pacts'),
});
beforeAll(() => provider.setup());
afterAll(() => provider.finalize());
test('GET /items mengembalikan inventaris yang tersedia', async () => {
await provider.addInteraction({
state: 'items exist',
uponReceiving: 'permintaan daftar item',
withRequest: {
method: 'GET',
path: '/items',
},
willRespondWith: {
status: 200,
headers: { 'Content-Type': 'application/json' },
body: [{ id: 1, name: 'Widget', qty: 42 }],
},
});
const response = await axios.get('http://localhost:1234/items');
expect(response.status).toBe(200);
expect(response.data).toEqual([{ id: 1, name: 'Widget', qty: 42 }]);
await provider.verify();
});
3. Publikasikan Contract
npx pact-broker publish ./pacts --consumer-app-version $(git rev-parse --short HEAD) --broker-base-url https://pact-broker.mycompany.com
4. Verifikasi Provider
Di sisi provider, tambahkan langkah verifikasi yang mengambil contract dari broker dan menjalankannya terhadap API yang sedang berjalan.
npx pact-verifier --provider-base-url http://localhost:3000 --pact-url https://pact-broker.mycompany.com/pacts/provider/InventoryService/consumer/OrderService/latest
Jika Sudah Punya OpenAPI/Swagger
Kalau tim kamu sudah punya file OpenAPI atau Swagger, contract testing bisa dimulai dari spesifikasi tersebut. Pendekatan ini cocok untuk provider contract test: memastikan API yang berjalan tetap sesuai dengan dokumentasi resmi.
Contohnya, dengan Dredd:
npx dredd ./openapi.yaml http://localhost:3000
Di CI, jalankan service terlebih dahulu, lalu validasi endpoint terhadap spec:
- Lint spec OpenAPI untuk menangkap error format atau schema.
- Start API di environment terisolasi seperti Docker atau container CI.
- Jalankan validator seperti Dredd atau OpenAPI validator terhadap base URL API.
- Gagalkan build jika response aktual tidak sesuai dengan spec.
Pola ini berbeda dari Pact. OpenAPI/Swagger bagus untuk menjaga provider tetap sesuai dokumentasi, sedangkan Pact lebih kuat untuk memastikan provider memenuhi kebutuhan consumer yang benar-benar dipakai.
Integrasi CI/CD
- Jalankan tes consumer pada setiap pull request.
- Publikasikan contract ke Pact Broker (atau simpan di repositori Git).
- Picu verifikasi provider di pipeline provider.
- Gagalkan build jika ada verifikasi contract yang gagal.
Sebagian besar platform CI (GitHub Actions, GitLab CI, Azure Pipelines) sudah menyediakan langkah siap pakai untuk Pact.
Best Practices
- Versi contract dengan semantic versioning; perlakukan perubahan breaking sebagai peningkatan mayor.
- Simpan contract di folder
contracts/khusus atau di Pact Broker. - Jaga contract tetap kecil - satu file per interaksi consumer-provider.
- Otomatisasi pembuatan stub yang bisa digunakan consumer selama pengembangan lokal.
- Jalankan verifikasi provider di environment terisolasi seperti Docker agar hasil tes tidak terpengaruh state lokal.
Kesalahan Umum & Cara Menghindarinya
| Kesalahan | Solusi |
|---|---|
| Terlalu bergantung pada contract dan mengabaikan tes integrasi | Pertahankan suite tes yang seimbang; contract melengkapi, bukan menggantikan, tes integrasi. |
| Contract menjadi usang | Tambahkan check di CI yang memastikan contract ikut diperbarui setiap kali API berubah. |
| Contract monolitik besar | Pecah contract berdasarkan resource atau gunakan pendekatan consumer‑driven untuk menjaga fokus. |
Kesimpulan
Contract testing adalah salah satu teknik yang kuat untuk menjaga kompatibilitas API di layanan yang terus berkembang. Dengan mendefinisikan contract yang jelas, mengotomatisasi verifikasi, dan mengintegrasikannya ke pipeline CI/CD, kamu dapat merilis perubahan dengan lebih percaya diri, mengurangi bug integrasi, dan menjaga ekosistem microservice tetap sehat.
Referensi
- Pact Documentation
- Pact Broker Documentation
- OpenAPI Specification
- Dredd Documentation
- Spring Cloud Contract Reference Documentation
Tim kamu sudah pakai contract testing di CI/CD? Ceritakan pengalaman, tool yang dipakai, atau tantangan paling besar saat menjaga kompatibilitas API di kolom komentar.
Artikel Terkait
Lanjutkan membaca topik yang masih satu konteks.
Testing Pyramid: Unit, Integration, dan E2E untuk Product Team
Terapkan testing pyramid pragmatic dengan unit, integration, dan E2E test agar kualitas naik tanpa test suite jadi lambat.
Strategi Testing Web App: Unit, Integration, dan E2E
Rancang strategi testing web app dari unit, integration, sampai E2E test dengan keputusan coverage dan tradeoff tooling yang praktis.
Docker untuk Developer: Dasar, Dockerfile, dan Compose
Belajar dasar Docker untuk developer, mulai dari image, container, Dockerfile, sampai workflow Docker Compose untuk development lokal.
GitOps: Kelola Infrastructure as Code dengan Git
Kelola infrastructure as code dengan GitOps, pull request, automated reconciliation, kontrol drift environment, dan deployment tools.