Belajar WebSocket - Testing WebSocket Applications
Episode 26 of 34

Belajar WebSocket - Testing WebSocket Applications

Episode ini membahas pengujian aplikasi WebSocket: unit testing server dengan Jest, integration testing klien-server, load testing dengan Artillery dan k6, serta chaos testing untuk simulasi kegagalan jaringan.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

Bug WebSocket sulit ditemukan manual: masalah muncul hanya saat banyak koneksi, saat koneksi putus di tengah jalan, atau saat pesan datang di luar urutan. Pengujian otomatis adalah satu-satunya cara memastikan semua skenario itu bekerja sebelum pengguna menemukannya.

Episode 26 membahas testing WebSocket applications dari unit hingga chaos: menguji logika server secara terisolasi, menguji interaksi klien-server, membanjiri server dengan load test, dan menyimulasikan kegagalan untuk melihat perilaku aplikasi.

Unit Testing

Menguji Logika Murni

Fungsi yang bisa diuji tanpa server adalah target unit test terbaik — pisahkan logika murni dari efek samping.

JSPisahkan logika untuk diuji
function bangunEnvelope(type, payload) {
  return {
    v: 2,
    type,
    id: "m_" + Date.now(),
    data: payload,
  };
}
 
module.exports = { bangunEnvelope };

bangunEnvelope(type, payload) murni: input sama, output sama, tanpa IO. Fungsi seperti ini diuji cepat dan memberi kepercayaan pada bagian yang paling sering berubah — format pesan.

Mock Koneksi

Untuk menguji handler yang bergantung pada objek WebSocket, gunakan mock.

JSTest handler dengan mock
test("menolak pesan tanpa tipe", () => {
  const mockWs = {
    send: jest.fn(),
    close: jest.fn(),
  };
 
  handlerPesan(mockWs, '{"teks":"halo"}');
 
  expect(mockWs.close).toHaveBeenCalledWith(1008, "format tidak valid");
});

mockWs menggantikan objek WebSocket sungguhan. Test menegaskan perilaku: close dipanggil dengan kode 1008 saat pesan tidak punya tipe.

Integration Testing

Menguji Klien dan Server Bersama

Integration test membuka server sungguhan di port test, lalu menghubungkan klien.

JSIntegration test dengan klien nyata
const WebSocket = require("ws");
 
test("klien menerima broadcast", async () => {
  const server = mulaiServer(0);
  const klien1 = new WebSocket("ws://localhost:" + server.port);
  const klien2 = new WebSocket("ws://localhost:" + server.port);
 
  await tungguTerbuka(klien1);
  await tungguTerbuka(klien2);
 
  klien1.send(JSON.stringify({ type: "chat", teks: "halo" }));
 
  const terima = await tungguPesan(klien2);
  expect(JSON.parse(terima).teks).toBe("halo");
 
  server.tutup();
});

mulaiServer(0) memakai port acak agar test tidak bentrok. Test ini memverifikasi skenario end-to-end: satu klien mengirim, klien lain menerima.

Test Lifecycle Koneksi

Uji juga fase hidup koneksi: handshake, pesan, penutupan normal, dan penutupan abnormal. Pastikan handler close, error, dan ping dipanggil sesuai skenario.

Load Testing

Artillery untuk WebSocket

Artillery membanjiri server dengan skenario koneksi.

Skrip load test Artillery
config:
  target: ws://localhost:8080
  phases:
    - duration: 60
      arrivalRate: 10
scenarios:
  - engine: ws
    flow:
      - send: '{"type":"chat","teks":"halo"}'
      - think: 1

arrivalRate: 10 membuka 10 koneksi baru per detik selama 60 detik. Hasilnya menunjukkan berapa koneksi maksimal yang bisa ditahan server sebelum latensi memburuk.

k6 dengan Ekstensi WebSocket

k6 menguji WebSocket dengan skrip JavaScript.

JSSkrip k6 WebSocket
import ws from "k6/ws";
import { check } from "k6";
 
export default function () {
  const res = ws.connect("ws://localhost:8080", (socket) => {
    socket.on("open", () => {
      socket.send('{"type":"chat","teks":"test"}');
    });
    socket.on("message", (data) => {
      check(data, { "ada balasan": (d) => d.length > 0 });
    });
  });
}

ws.connect(...) di k6 membuka koneksi, mengirim pesan, dan memverifikasi balasan. Jalankan dengan k6 run script.js untuk melihat metrik seperti waktu koneksi dan persentil respons.

Chaos Testing

Simulasi Kegagalan

Chaos testing sengaja memutus koneksi untuk melihat apakah sistem pulih.

JSSimulasi putus koneksi
test("reconnect memulihkan room", async () => {
  const klien = bukaKoneksi();
  klien.emit("room:join", "kritikal");
 
  // paksa koneksi terputus
  klien.disconnect();
 
  klien.connect();
  await tungguKoneksi(klien);
 
  expect(klien.rooms).toContain("kritikal");
});

klien.disconnect() lalu klien.connect() menyimulasikan jaringan putus. Test memverifikasi klien kembali ke room setelah reconnect — persis perilaku yang dibahas di episode 12.

Skenario Chaos Lain

Selain putus koneksi, uji juga:

  • High latency: tunda pesan untuk melihat timeout dan retry.
  • Slow network: kurangi bandwidth untuk menguji backpressure.
  • Server crash: matikan server dan pastikan klien mencoba kembali.
  • Out-of-order: kirim pesan tidak berurutan untuk menguji sequence number.

Penutup

Episode 26 melengkapi kalian dengan jaring pengaman: unit test untuk logika, integration test untuk interaksi nyata, load test untuk kapasitas, dan chaos test untuk ketahanan.

Inti yang harus dibawa pulang:

  • Pisahkan logika murni dari IO agar mudah diuji.
  • Mock objek WebSocket untuk unit test handler.
  • Integration test memakai server sungguhan di port acak.
  • Artillery dan k6 mengukur kapasitas dengan skenario nyata.
  • Chaos testing menyimulasikan putus koneksi, latensi, dan crash.
  • Uji lifecycle lengkap: handshake, pesan, dan penutupan.

Di episode 27 berikutnya kita membahas Docker & containerization: Dockerfile untuk server WebSocket, multi-stage build, docker networking, Docker Compose dengan Redis, dan health check.

Belajar WebSocket - Testing WebSocket Applications | Belajar WebSocket