Contract Testing: Menjamin Kompatibilitas API
Mengapa Contract Testing Penting
Dalam arsitektur microservice, layanan berkomunikasi melalui API. Perubahan pada satu layanan dapat secara tidak sengaja merusak layanan lain, menyebabkan kegagalan runtime yang mahal. Contract testing menyelesaikan masalah ini dengan memverifikasi bahwa penyedia dan konsumen sepakat pada bentuk request dan response sebelum mereka dideploy.
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
- Integrasi CI/CD
- Best Practices
- Kesalahan Umum & Cara Menghindarinya
- Kesimpulan
Apa Itu Contract?
Contract adalah deskripsi mesin‑readable dari interaksi API. Bisa diekspresikan dalam:
- Spesifikasi OpenAPI/Swagger (JSON atau YAML)
- DSL Pact (JSON atau YAML) untuk contract yang digerakkan konsumen
- Skema GraphQL introspection
Contract disimpan di repositori bersama dan di‑version‑control bersama kode layanan.
Manfaat Contract Testing
| Manfaat | Penjelasan |
|---|---|
| Deteksi Dini | Kegagalan contract terdeteksi selama unit testing, bukan di produksi. |
| Pengembangan Terpisah | Konsumen dapat men-stub penyedia menggunakan contract, memungkinkan pengembangan paralel. |
| 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, mendukung broker untuk versioning. |
| OpenAPI Validator | JS, Python, Java | ❌ (fokus provider) | Cocok bila API didefinisikan terlebih dahulu. |
| Dredd | Node.js | ✅ | Menjalankan deskripsi API terhadap layanan yang hidup. |
| 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 Konsumen
// 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 hidup.
npx pact-verifier --provider-base-url http://localhost:3000 --pact-url https://pact-broker.mycompany.com/pacts/provider/InventoryService/consumer/OrderService/latest
Integrasi CI/CD
- Jalankan tes konsumen pada setiap pull request.
- Publikasikan contract ke Pact Broker (atau simpan di repositori Git).
- Trigger 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 konsumen‑provider.
- Otomatisasi pembuatan stub untuk konsumen gunakan selama pengembangan lokal.
- Jalankan verifikasi provider di lingkungan bersih (Docker) untuk menghindari state tersembunyi.
Kesalahan Umum & Cara Menghindarinya
| Kesalahan | Solusi |
|---|---|
| Terlalu bergantung pada contract, mengabaikan tes integrasi | Pertahankan suite tes seimbang; contract melengkapi, bukan menggantikan, tes integrasi. |
| Contract menjadi usang | Tegakkan cek CI yang mewajibkan pembaruan contract setiap kali ada perubahan API. |
| Contract monolitik besar | Pecah contract berdasarkan resource atau gunakan pendekatan consumer‑driven untuk menjaga fokus. |
Kesimpulan
Contract testing adalah teknik kuat untuk menjamin kompatibilitas API di layanan yang terus berkembang. Dengan mendefinisikan contract yang jelas, mengotomatisasi verifikasi, dan mengintegrasikannya ke pipeline CI/CD, Kamu dapat mengirim perubahan dengan percaya diri, mengurangi bug integrasi, dan menjaga ekosistem microservice yang sehat.