Skip to Content

Debugging

Glubean tests are real Node.js code. You can import any npm package — crypto libraries, database clients, file parsers, third-party SDKs — and debug them with the full power of VS Code’s debugger. This is something GUI tools like Postman fundamentally cannot do: when a crypto function returns an unexpected hash, or a third-party SDK throws a cryptic error, you need to set a breakpoint and inspect the actual runtime state.

Breakpoints in test code

Glubean tests run on Node, which exposes the V8 inspector that VS Code already understands.

To debug a test:

  1. Set a breakpoint anywhere in your *.test.ts file — click the gutter to the left of a line number.
  2. Right-click the Play button next to the test( call and choose Debug Test, or select it from the Test Explorer context menu.
  3. Execution pauses at your breakpoint.

Tip: Right-click any Play button and select “Debug Test” to enter debug mode. You can also use the bug icon in Test Explorer.

From there you can:

  • Step through lines with F10 / F11
  • Inspect variables in the Run and Debug sidebar
  • Evaluate expressions in the Debug Console
  • Hover over any variable in the editor to see its current value

When debugging matters most

Third-party libraries and crypto

When your test involves npm packages beyond HTTP, the debugger is essential — you can’t “trace” a crypto function or a database query the way you trace an HTTP call.

import { createHmac } from "node:crypto"; import { test } from "@glubean/sdk"; export const verifyWebhook = test("verify-webhook", async (ctx) => { const secret = ctx.secrets.require("WEBHOOK_SECRET"); const payload = '{"event":"order.created"}'; const signature = createHmac("sha256", secret) .update(payload) .digest("hex"); // set a breakpoint here — inspect the actual hash const res = await ctx.http.post("/webhooks", { body: payload, headers: { "x-signature": signature, "content-type": "application/json", }, }); ctx.expect(res).toHaveStatus(200); });

Inspecting HTTP responses

export const createAndFetch = test("create-and-fetch") .step("create", async (ctx) => { const res = await ctx.http.post("/api/users", { json: { name: "Alice" } }); const body = await res.json(); // set a breakpoint here return { id: body.id }; }) .step("fetch", async (ctx, { id }) => { const res = await ctx.http.get(`/api/users/${id}`); ctx.expect(res.status).toBe(200); });

Pause after any await and inspect the result directly in the debug console — response body, intermediate variables, computed values — before the assertion runs.

Tips

Use ctx.log() for lightweight tracing — if you just want to understand the flow without stopping execution, ctx.log() writes structured output to the trace file and the terminal. No debugger needed.

ctx.log("User created", { id: body.id, status: res.status });

Step over await calls — use F10 to step over async calls and land on the next line after the promise resolves, rather than stepping into the runtime internals.

Debug Console expressions — while paused, type any expression in the Debug Console to evaluate it in the current scope:

> res.status 200 > JSON.stringify(body, null, 2) '{\n "id": 42,\n "name": "Alice"\n}'

One test at a time — the debugger runs a single test per session. This is inherent to how debugging works.

What’s next?

Last updated on