Testland
Browse all skills & agents

vercel-edge-runtime-testing

Wraps Vercel Edge Runtime testing patterns: the @edge-runtime/jest-environment + edge-runtime CLI for executing Web-Standard APIs (Request / Response / fetch) in jest tests, the `vercel dev` local emulator for full route testing, and the Edge vs Node Function divergence (no fs, no Buffer; Request / Response only). Covers the 30s Edge function timeout per vercel.com/docs. Use when testing Vercel Edge Functions or middleware.

Install with skills.sh (any agent)

npx skills add testland/qa --skill vercel-edge-runtime-testing
View source

vercel-edge-runtime-testing

Overview

Vercel Edge Runtime is V8-isolate-based (sub-30ms cold starts per cold-start-budget-reference) with a constrained API surface: no filesystem access, so no Node fs or child_process ("you can't read or write to the filesystem"). Buffer is an exception, being "globally exposed to maximize compatibility with existing Node.js modules". Per vercel.com/docs/functions/edge-runtime (opens in new window), "The Edge runtime provides a subset of Web APIs such as fetch, Request, and Response."

Tests need the same constraints. Vercel ships @edge-runtime/jest-environment (and standalone edge-runtime CLI) for this.

When to use

  • Unit tests for Vercel Edge Functions or middleware.
  • Tests for code that uses only Web Platform APIs (intentional Edge target).
  • Routing / middleware tests with vercel dev integration.

Authoring

Install

npm install --save-dev @edge-runtime/jest-environment edge-runtime

Jest config

{
  "jest": {
    "testEnvironment": "@edge-runtime/jest-environment"
  }
}

This swaps Jest's default jsdom / node env for an Edge- constrained one. Tests that try to import fs or use Buffer fail - same as production.

Edge function example

// pages/api/hello.ts (Vercel Edge Function)
export const config = { runtime: 'edge' };

export default async function handler(req: Request): Promise<Response> {
  return new Response(JSON.stringify({ ok: true }), {
    headers: { 'Content-Type': 'application/json' },
  });
}

Test the handler

import handler from './hello';

test('returns ok', async () => {
  const req = new Request('https://example.com/api/hello');
  const res = await handler(req);
  expect(res.status).toBe(200);
  expect(await res.json()).toEqual({ ok: true });
});

Middleware

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith('/admin')) {
    if (!request.cookies.get('session')) {
      return NextResponse.redirect(new URL('/login', request.url));
    }
  }
  return NextResponse.next();
}

Test middleware

import { middleware } from './middleware';

test('redirects unauthenticated /admin', () => {
  const request = new Request('https://example.com/admin/dashboard');
  const response = middleware(request as any);
  expect(response.status).toBe(307);  // redirect
  expect(response.headers.get('location')).toContain('/login');
});

test('allows authenticated', () => {
  const request = new Request('https://example.com/admin', {
    headers: { cookie: 'session=valid' },
  });
  const response = middleware(request as any);
  expect(response.headers.get('x-middleware-next')).toBe('1');  // NextResponse.next sentinel
});

vercel dev (CLI)

npm install -g vercel
vercel dev --listen 3000

Routes are served exactly as on prod. Now run e2e tests against http://localhost:3000.

edge-runtime CLI for ad-hoc

npx edge-runtime ./pages/api/hello.ts
# Spins up a local server in the Edge Runtime environment

Running

npx jest

CI integration

jobs:
  vercel-edge-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
      - run: npm ci
      - run: npx jest

Anti-patterns

Anti-patternWhy it failsFix
Use jsdom test env for Edge codeTests pass; Buffer.from(...) works in test but not prodUse @edge-runtime/jest-environment
Importing fs / Buffer in handlerTests fail (good); but production fails tooUse Web Platform APIs (Uint8Array, TextEncoder)
Hardcoded path in testOS-specificUse Request URL
Skipping middleware testsAuth bypass slips throughAlways test middleware separately
No 30s timeout testEdge functions have 30s wall-clock max per lambda-timeout-budget-referenceTest with artificial slowness; assert proper response
Mocking Request / ResponseLoses standard-complianceUse real Request / Response (Edge env provides them)
Skip vercel dev for route-testsMisses routing layerRun e2e against vercel dev

Limitations

  • 30 second hard timeout. Per vercel.com/docs/functions/edge-runtime (opens in new window), Edge Functions are killed at 30s. No grace.
  • Streaming responses can extend beyond 30s for the body but headers must commit early.
  • Cold-start budget different per cold-start-budget-reference.
  • No Node-specific dependencies. Edge can't run Node-only packages. Pair with Node Functions for those.
  • Doesn't test the Vercel CDN layer. Caching / rewrites / redirects above the function are CDN-level.

References

Related skills

aws-sam-local-testing

Wraps AWS SAM (Serverless Application Model) Local CLI for testing Lambda functions locally: `sam local invoke` (single invocation with event payload), `sam local start-api` (local API Gateway emulator), `sam local start-lambda` (local Lambda invoke endpoint for AWS SDK clients), and event-payload generation (`sam local generate-event`). Use when testing Lambda + API Gateway + integrated AWS services locally.

azure-functions-tests

Runs Azure Functions locally using Azure Functions Core Tools v4 (`func start`), Azurite storage emulation, and framework-native unit tests for handler code (.NET isolated worker model, Node.js v4, Python v2). Covers HTTP, queue, and timer trigger testing, admin-endpoint invocation for non-HTTP triggers, and binding verification via local.settings.json. Use when testing Azure Functions before deployment, reproducing trigger behaviour without live Azure services, or gating function handler logic in CI.

cloudflare-workers-miniflare

Wraps Miniflare 3 (the official Cloudflare Workers simulator) and Wrangler dev for testing Workers locally. Covers Miniflare's getMiniflare() programmatic API (workerd-backed simulation matching prod), the wrangler dev local-mode (live-reload during dev), KV / Durable Objects / R2 / D1 bindings emulation, and Vitest + @cloudflare/vitest-pool-workers for in-process tests. Use when testing Cloudflare Workers code locally.

cold-start-budget-reference

Pure-reference catalog of cold-start budgets across serverless runtimes. Covers AWS Lambda's three-phase cold start (Init: download+unzip+runtime-bootstrap; Init code: imports + module load; Invoke: handler execution), Cloudflare Workers' isolate model (sub-millisecond cold starts via V8 isolates per developers.cloudflare.com), Vercel Edge Runtime, Lambda SnapStart for JVM (snapshot-restore for Java), and provisioned-concurrency trade-offs. Includes per-runtime typical cold-start ranges and the testable behaviours each model creates. Use when designing latency budgets, choosing a runtime, or auditing cold-start variance in production.

lambda-test-tools-net

Wraps Amazon.Lambda.TestTool (the canonical .NET Lambda local-testing toolkit from github.com/aws/aws-lambda-dotnet) for invoking Lambda handlers from xUnit / NUnit tests with simulated AWS Lambda contexts (ILambdaContext, ILambdaSerializer). Covers handler-direct invocation, mock context fixtures, the dotnet-lambda CLI, and integration with the .NET LambdaSerializer for JSON. Use when testing AWS Lambda functions written in C#/.NET.

lambda-timeout-budget-reference

Pure-reference catalog of AWS Lambda timeout + billing semantics. Covers Lambda's hard 15-minute (900s) wall-clock limit, the timeout-vs-deadline relationship (Lambda Context.getRemainingTimeInMillis), per-invocation billing (rounded to 1ms; per-invocation + duration × memory), the memory-vs-CPU relationship (CPU scales linearly with memory), the integration-timeout cascade (API Gateway 29s → Lambda 15min; SQS visibility-timeout vs Lambda timeout), and per-runtime nuances. Use when designing a Lambda's timeout config, debugging timeout-vs-billing surprises, or sizing memory for compute-bound workloads.

netlify-functions-tests

Wraps Netlify Functions testing patterns: Netlify Dev (`netlify dev`) for local routing emulation, the @netlify/functions handler API testing pattern, Netlify Edge Functions (Deno runtime) vs Background Functions (Lambda under the hood) distinction, and scheduled-function (cron) test patterns. Use when testing Netlify Functions or Edge Functions.

serverless-framework-test-plugin

Wraps the Serverless Framework (serverless.com) test ecosystem: serverless-offline (local HTTP emulator), serverless-jest-plugin / serverless-mocha-plugin (per-runtime test runners), and the `serverless invoke local` CLI for one-off invocations. Use when testing Lambda functions deployed via the Serverless Framework.

serverless-integration-test-builder

Workflow-driven skill that builds the integration-test suite for a serverless application from its IaC definition (SAM template / serverless.yml / Wrangler config / Vercel functions / Netlify functions). Walks through: identifying the function inventory + event sources, picking the right local-emulator per function (sam local / Miniflare / netlify dev / vercel dev / serverless-offline), generating test events per event source, asserting on cold-start + timeout budgets, and emitting the test directory + CI config. Use when introducing integration tests to a serverless project.