Strategi Testing Komprehensif untuk API Route Next.js yang Stabil dimulai dengan menjawab kebutuhan paling mendesak: memastikan API route tetap berfungsi setelah perubahan kode tanpa mengorbankan kecepatan rilis. Di artikel ini, Anda akan menemukan pendekatan terstruktur dengan unit testing, integration testing, dan end-to-end testing, lengkap dengan simulasi HTTP, mock yang tepat, serta pendekatan observabilitas dan review kegagalan di pipeline.

Pendekatan Testing Berlapis untuk API Route

Next.js mengekspose API route sebagai handler yang bereaksi terhadap request HTTP. Karena konteksnya hampir serupa dengan serverless function, lapisan testing harus mencakup isolasi logika, interaksi service, dan perilaku nyata terhadap HTTP client. Berikut struktur lapisan yang direkomendasikan:

  • Unit Testing: Fokus pada handler logic tanpa menjalankan HTTP server.
  • Integration Testing: Menguji handler dengan middleware, database, dan external service menggunakan mock yang mendekati aslinya (misalnya menggunakan msw atau nock).
  • End-to-End Testing: Menjalankan simulasi HTTP penuh (via Playwright, cURL, atau Postman) terhadap API route yang sebenarnya dalam environment staging.

Strategi ini mengurangi false positive/negative: unit tests cepat dan memberi umpan balik awal sementara integration dan e2e menangkap regression yang hanya muncul saat beberapa komponen berinteraksi.

Unit dan Integration Testing dengan Jest dan Mock

Untuk unit testing, jest menyediakan mocking modul built-in dan snapshot. Dalam konteks API route, pastikan Anda mengekspor handler terpisah agar mudah diimpor tanpa menjalankan server Next.js.

import { createMocks } from 'node-mocks-http';
import handler, { getDependencies } from '@/pages/api/orders';

test('mengembalikan 200 dengan payload valid', async () => {
  const { req, res } = createMocks({
    method: 'POST',
    body: { sku: 'ABC', quantity: 2 }
  });

  const dependencies = getDependencies({ db: mockDb, logger: mockLogger });
  await handler(req, res, dependencies);

  expect(res._getStatusCode()).toBe(200);
  expect(res._getJSONData()).toMatchObject({ success: true });
});

Catatan teknik: pisahkan pembuatan dependency (database, queue, logger) sehingga bisa diganti dengan mock atau spy. Integration test bisa memperluas pendekatan ini dengan msw atau nock untuk mem-mock request ke service eksternal, lalu validasi status response dan interaksi database.

End-to-End Testing dan Simulasi HTTP

E2E testing harus memverifikasi request nyata terhadap API route di environment staging. Playwright atau alat sejenis bisa menjadi pilihan utama karena mendukung pengujian HTTP dan browser sekaligus.

import { test, expect } from '@playwright/test';

test('API order dapat dipanggil dari UI', async ({ request }) => {
  const response = await request.post('http://staging.example.com/api/orders', {
    data: { sku: 'ABC', quantity: 2 }
  });

  expect(response.status()).toBe(200);
  const body = await response.json();
  expect(body.success).toBe(true);
});

Uji E2E juga harus memverifikasi header (autentikasi, tracing), response time, dan status error. Jika API route berjalan di edge runtime, pastikan test environment meniru batasan resource agar hasilnya relevan.

Deteksi Flaky Test dan Pencegahan Regression

Flaky test paling sering muncul karena ketergantungan terhadap waktu, jaringan, atau state global. Langkah-langkah berikut membantu deteksi dan mitigasinya:

  • Re-run otomatis: Pipeline CI sebaiknya mengizinkan sekali retry sebelum memutuskan failure, tetapi hasil retry harus dipantau agar jangan menjadi "flaky accepted".
  • Deteksi state shared: Reset mock/DB sebelum setiap test. Gunakan database ephemeral (SQLite in-memory) atau factory pattern yang mengembalikan data baru.
  • Pengukuran durasi: Catat waktu eksekusi test. Flaky sering disertai lonjakan durasi yang tidak stabil.

Untuk regression, jalankan kombinasi test suite: unit setiap commit, integration di branch merge, dan e2e di staging dengan data sintetis. Gunakan label/pipeline stage untuk memastikan tidak ada skip otomatis yang menjadikan regression lolos.

Struktur Suite dan Observabilitas

Sebagai contoh struktur folder:

  1. tests/unit/api/orders.test.ts – handler logic.
  2. tests/integration/api/orders.integrations.ts – mock database, service, dan middleware.
  3. tests/e2e/orders.e2e.ts – Playwright.

Observabilitas juga penting. Pastikan setiap test suite mencatat logs yang bisa dikumpulkan (misalnya jest reporters menyimpan output JSON). Di CI/CD, kumpulkan metrics seperti rata-rata waktu eksekusi, jumlah failure per suite, dan coverage API response. Log yang lengkap mempermudah debugging ketika API route menolak request karena validasi atau autentikasi.

Workflow Review Kegagalan Test di CI/CD

Workflow yang menjaga keandalan rilis biasanya seperti ini:

  1. Commit dan push: Unit test ter-trigger langsung dan hasilnya dilaporkan di PR.
  2. Merge request: Integration dan Smoke test dijalankan di pipeline pre-merge.
  3. Deploy staging: E2E testing dipicu setelah deploy, khususnya API route yang terhubung ke environment staging.

Ketika failure terjadi, berikut pendekatan review:

  • Identifikasi log paling awal dan trace ID request.
  • Periksa apakah failure disebabkan async race condition (flakiness) atau regression logis.
  • Catat failure sebagai issue jika test baru atau flaky, lalu bundel bersama perbaikan kode untuk release berikutnya.

Dengan pendekatan peer review terhadap test results, tim bisa memutuskan apakah harus membatalkan release, memperbaiki test, atau merilis dengan mitigasi sementara.

Kesimpulan

Strategi testing komprehensif untuk API Route Next.js yang stabil menyeimbangkan coverage dan kecepatan feedback. Kombinasi unit, integration, dan e2e memastikan berbagai jenis regression tertangani, sementara observabilitas dan workflow CI/CD membuat failure mudah ditelusuri. Dengan struktur suite, simulasi HTTP, dan proses review teratur, tim bisa mempertahankan kepercayaan terhadap API route di setiap rilis.