Quick start
From an empty project to a test running on a real cluster.
You need Docker, k3d, kubectl, Vitest 5 and Node ^22.18, ^24.11 or >=26.
npm install --save-dev vitest vitekube
1. Name your cluster
In k8s.setup.ts:
import { defineK8sGlobalSetup } from "vitekube/node";
export default defineK8sGlobalSetup({
cluster: { provider: "k3d", name: "my-app-tests", reuse: true },
});
2. Connect it to Vitest
In vitest.config.ts:
import { K8sReporter } from "vitekube/node";
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
globalSetup: ["./k8s.setup.ts"],
reporters: [new K8sReporter()],
fileParallelism: false,
testTimeout: 180_000,
teardownTimeout: 120_000,
},
});
K8sReporter is Vitest's default output with readable times, 38.2s rather than 38196ms, and it fails a run whose -t filter matches nothing.
3. Add your YAML
In web.yaml:
apiVersion: apps/v1
kind: Deployment
metadata: { name: web }
spec:
selector: { matchLabels: { app: web } }
template:
metadata: { labels: { app: web } }
spec:
containers:
- { name: web, image: nginx:1.29-alpine }
---
apiVersion: v1
kind: Service
metadata: { name: web }
spec:
selector: { app: web }
ports: [{ port: 80 }]
4. Write a test
In web.test.ts:
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);
});
5. Run it
npx vitest run
The first run creates the cluster. With reuse: true, every run after that starts straight away. Leave out reuse to get a new cluster each run, deleted at the end.
Each run also prints a command for watching the cluster live in k9s.