Menghadapi middleware kritis di Express, cara paling langsung mencegah regresi adalah menerapkan Test Middleware Express yang terarah. Artikel ini membahas praktik kontrak, identifikasi flaky test, regression suite berlapis, dan workflow pra-rilis untuk memastikan perubahan middleware tidak merusak aliran request.
Strategi Kontrak untuk Middleware Kritis
Middleware biasanya bertugas memvalidasi, mengautentikasi, atau meneruskan data ke lapisan berikutnya. Karena itu, fokus pertama adalah mendefinisikan kontrak input-output agar test tidak bergantung pada implementasi internal.
Menetapkan Kontrak Input-Output
Contohnya, middleware auth harus memeriksa header Authorization dan menambahkan objek req.user. Kontraknya bisa diuji dengan membuat request tiruan dan memastikan next dipanggil atau response 401 dikembalikan:
it('menolak tanpa header Authorization', async () => {
const req = { headers: {} };
const res = { status: jest.fn().mockReturnThis(), json: jest.fn() };
const next = jest.fn();
await authMiddleware(req, res, next);
expect(res.status).toHaveBeenCalledWith(401);
expect(next).not.toHaveBeenCalled();
});
Kontrak seperti ini memastikan behavior awal tetap stabil meskipun logika autentikasi berubah.
Menguji Reaksi terhadap Dependensi Eksternal
Banyak middleware bergantung pada layanan seperti Redis, database, atau API pihak ketiga. Gunakan contract test dengan mock yang meniru perilaku layanan tertentu:
jest.mock('../services/sessionStore');
it('menyimpan session ketika valid', async () => {
sessionStore.save.mockResolvedValue(true);
const req = { headers: { authorization: 'Bearer abc' } };
const res = { locals: {} };
const next = jest.fn();
await sessionMiddleware(req, res, next);
expect(sessionStore.save).toHaveBeenCalledWith(expect.objectContaining({ userId: '123' }));
expect(next).toHaveBeenCalled();
});
Kontrak ini fokus memastikan middleware memanggil dependensi dengan pola data yang tepat. Jika dependensi berubah API-nya, test ini akan gagal lebih awal.
Mendeteksi dan Mengatasi Flaky Test
Flaky test menandakan ketergantungan lingkungan atau state global. Untuk middleware, penyebab umum: clock bergantung pada real time, database tidak di-reset, atau parallel request saling mengganggu.
- Stabilkan data dasar: seed database dan rollback setiap test agar state deterministik.
- Kontrol waktu: gunakan fake timer (misalnya
jest.useFakeTimers()) jika middleware memanfaatkanDate.now()atau timeout. - Log request/respons: tambahkan log tingkat debug untuk setiap test gagal sehingga bisa dibandingkan dengan run sebelumnya.
- Isolasi global: hindari menyimpan state di modul; gunakan dependency injection agar middleware bisa diuji tanpa global variable.
Ketika flaky muncul, jalankan kembali test dengan flag --runInBand atau skrip terpisah agar bisa mempersempit penyebab.
Regression Suite Berlapis
Untuk mengurangi risiko regresi, susun set test berlapis:
1) Unit test untuk logic internal, 2) Integration test untuk interaksi middleware dengan dependensi, dan 3) Regression suite yang dijalankan dalam pipeline.
Unit dan Integration
Unit test memastikan fungsi middleware di level isolasi tetap konsisten. Integration test harus menjalankan Express app sederhana agar request flow diukur bersama modul lain, misalnya:
const request = require('supertest');
const app = require('../app');
test('middleware logging tidak mengganggu response', async () => {
const res = await request(app)
.get('/protected')
.set('Authorization', 'Bearer token');
expect(res.status).toBe(200);
});
Integration test ini bisa dijalankan di regression suite untuk memastikan middleware tidak mengubah status code atau header.
Smoke dan End-to-End sebagai Regression Layer
Regression suite terpisah (misalnya npm run regression) harus menjalankan subset test yang mencakup middleware kritis dalam urutan aliran request lengkap. Setiap PR harus memicu smoke test yang hanya menjalankan middleware-dependant endpoint utama sebelum merge.
Workflow Pra-rilis untuk Verifikasi Middleware
Workflow pra-rilis menyaring perubahan dengan langkah-langkah berikut:
- Lint & Static Analysis: catch pattern yang mungkin mengubah behavior middleware (misalnya penghapusan
next()). - Regression Suite: jalankan test berlapis di env CI. Bagi ke dalam job terpisah agar hasil failure menunjukkan layer mana yang bermasalah (unit vs integration vs smoke).
- Staging Smoke Test: deploy ke staging dan kirim request ke aliran middleware terkritis. Gunakan data real fixture dengan header dan payload yang mewakili kasus produksi.
- Pre-approved Canary: jika memungkinkan, aktifkan middleware baru untuk persentase kecil request untuk memonitor log error.
Workflow ini memungkinkan setiap perubahan middleware diuji dalam konteks sebenarnya sebelum menyebar ke produksi.
Penutup dan Debugging Tips
Selalu dokumentasikan kontrak middleware dan dependensi eksternal di repositori. Bila regression suite gagal, periksa apakah ada perubahan lingkungan (misalnya URL service berbeda). Gunakan verbose log untuk melihat header/respons asli ketika test integration gagal.
Dengan kontrak yang eksplisit, deteksi flaky secara sistematis, regression suite berlapis, dan workflow pra-rilis yang terstruktur, Test Middleware Express dapat mengurangi regresi dan menjaga aliran request tetap stabil.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!