Environment & Secrets
The ctx.vars and ctx.secrets objects provide access to environment variables and secure secrets during test execution.
Purpose
To separate configuration (URLs, regions, flags) from sensitive credentials (API keys, OAuth tokens) and provide a type-safe, strict way to access them.
Design Rationale
- Strict by Default: Both objects provide a
require()method. Missing configuration is the #1 cause of confusing test failures.require()guarantees that if a necessary variable is missing or invalid, the test fails immediately with a clear error message, rather than failing 30 lines later with a cryptic “Cannot read property of undefined”. - Separation of Secrets: Secrets are handled via a separate
ctx.secretsobject. This distinct boundary ensures that the runner knows exactly which values are sensitive. The runner automatically redacts these values from logs, traces, and assertions before they are stored or displayed in the Glubean dashboard.
Scenarios
Required vs. Optional Configuration
When your test cannot proceed without a specific environment variable, use require(). When you have a sensible fallback, use get().
export const healthCheck = test("health", async (ctx) => {
// Fails immediately if BASE_URL is not set in the environment
const baseUrl = ctx.vars.require("BASE_URL");
// Falls back to "us-east-1" if REGION is not set
const region = ctx.vars.get("REGION") ?? "us-east-1";
});Accessing Secrets
Secrets should always be accessed via ctx.secrets. Never place API keys in ctx.vars.
export const testAuth = test("auth", async (ctx) => {
// Fails immediately if API_KEY is missing
const apiKey = ctx.secrets.require("API_KEY");
const res = await ctx.http.get("...", {
headers: { Authorization: `Bearer ${apiKey}` }
});
});Validation Functions
You can pass a validator function to require() to ensure the variable or secret is not just present, but structurally valid. This prevents sending malformed requests to your API.
export const validateConfig = test("validate", async (ctx) => {
// Validates that the port is a number
const port = ctx.vars.require("PORT", (v) => !isNaN(Number(v)));
// Validates that a JWT token has exactly 3 parts
const jwt = ctx.secrets.require("JWT_TOKEN", (v) => {
const parts = v.split(".");
if (parts.length !== 3) {
return "must be a valid JWT containing 3 parts separated by dots";
}
return true;
});
});Last updated on