Ringkasan eksekutif

Saya baca repo vitekube, proyek komunitas (bukan bagian resmi Vitest/Vite/Kubernetes) yang menyuntikkan fixture k8s, namespace, scope, dan evidence ke dalam test Vitest biasa supaya bisa jalan di cluster k3d nyata. Yang menarik: cluster dipertahankan antar run, dan sistem build-nya cuma mengulang image/stage yang inputnya berubah, jadi rerun bisa selesai dalam hitungan detik.

Masalah yang diselesaikan

Selama ini tes Kubernetes itu lambat dan menyebalkan untuk didebug: bikin cluster baru tiap run, rebuild seluruh sistem untuk perubahan kecil, jalankan ulang semua test cuma untuk cek satu kasus, dan begitu ada cleanup, jejak kegagalan (event, log, state pod) sudah lenyap. Vitekube menyerang semua titik lambat itu sekaligus: cluster bisa di-reuse lewat opsi reuse: true, tiap test dapat namespace sendiri yang dihapus otomatis setelah selesai, dan evidence (events, pod state, logs) ditangkap sebelum cleanup lalu ditempel langsung di output kegagalan.

Fitur utama dan contoh kode

Intinya cuma test biasa dari Vitest yang dibekali fixture k8s, namespace, scope, dan evidence. Contoh dari dokumentasinya:

import { test } from "vitekube";
import { expect } from "vitest";

test("the web server answers", async ({ k8s, namespace }) => {
  await k8s.applyFile(namespace, "web.yaml");
  await k8s.waitForRollout({ namespace, name: "web" }, { timeoutMs: 120_000 });

  await using web = await k8s.portForward({
    namespace,
    resource: "service/web",
    remotePort: 80,
  });

  expect((await fetch(web.url)).status).toBe(200);
});

Yang saya suka: k8s.get membedakan "resource memang tidak ada" dari error koneksi/permission (null hanya kalau API server mengonfirmasi tidak ada), dan fungsi wait seperti waitForJobCompletion langsung throw begitu Job gagal, tanpa menunggu timeout habis.

Bisa juga dibungkus jadi fixture sendiri lewat .extend, supaya test-nya terbaca seperti perilaku produk, bukan boilerplate k8s:

// fixtures.ts
import { test as base } from "vitekube";

export const test = base.extend("web", async ({ k8s, namespace }, { onCleanup }) => {
  await k8s.applyFile(namespace, "web.yaml");
  await k8s.waitForRollout({ namespace, name: "web" }, { timeoutMs: 120_000 });
  const forward = await k8s.portForward({ namespace, resource: "service/web", remotePort: 80 });
  onCleanup(() => forward.close());
  return { get: (path: string) => fetch(new URL(path, forward.url)) };
});

Untuk sistem yang lebih besar, defineK8sGlobalSetup (dari vitekube/node) menerima deklarasi images, stages, charts, dan dependsOn di satu tempat — jadi bisa pakai Helm chart produksi yang sama untuk tes. Contoh log yang ditunjukkan: kalau cuma satu source file berubah, stage database dan migrations tetap skipped, unchanged, cuma stage api yang running, because its inputs changed.

Untuk simulasi kegagalan ada scaleTemporarily (scale down sementara, auto-restore walau test throw/timeout), dan untuk menjaga secret dari output ada evidence.markSensitive(token) (menghapus nilai termasuk bentuk base64/JSON-nya) atau evidence.restrict() kalau secret berisiko muncul dalam bentuk yang tidak terdeteksi.

Dampak dan catatan upgrade

Syaratnya: Docker, k3d, kubectl, Vitest 5, dan Node ^22.18, ^24.11, atau >=26. Instalasinya npm install --save-dev vitest vitekube, lalu daftarkan K8sReporter dan globalSetup di vitest.config.ts dengan fileParallelism: false (karena isolasi cluster-scoped belum dijamin antar file paralel). Beberapa env var operasional yang disebut: VITEKUBE_REBUILD=1 untuk memaksa rebuild semua image/stage, VITEKUBE_CLUSTER=<nama> untuk memisahkan cluster per worktree/agent (dua run yang berbagi cluster akan gagal, bukan bertabrakan), dan VITEKUBE_KEEP_ON_FAILURE=1 untuk menahan namespace test yang gagal agar bisa diperiksa manual. Saat ini hanya provider k3d yang didukung untuk cluster terkelola; cluster yang sudah ada bisa dipakai lewat provider: "attached" tapi ditolak kecuali membawa marker vitekube atau context-nya dikonfirmasi lewat allowUnmarkedContext. Karena ini masih status "early" dan proyek komunitas independen, saya akan treat ini sebagai eksperimen di CI/local dev dulu, bukan langsung ganti setup e2e Kubernetes yang sudah mapan.

---

Pertama diumumkan di Hacker News: Show HN. Baca sumber aslinya untuk detail lengkap.

Baca juga