ZuploZuplo
LoginStart for Free
  • Documentation
  • API Reference
Getting Started
    Develop in the portal
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingDynamic MCP Server - Quickstart
    Develop locally with the CLI
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingDynamic MCP Server - Quickstart
Concepts
API Management
AI Gateway
MCP Gateway
MCP Server
Developer Portal
Development
    CORSEnvironment VariablesBranch-Based DeploymentsTroubleshootingGitOps vs TerraformCustom Code
    Testing
      Get startedTest recipesPreview environmentsTest deployments
    Local Development
    Guides
Deploying & Source Control
Analytics
Observability
Networking & Infrastructure
Account Management
Programming API
Build with AI
Zuplo CLI
Migration Guides
Platform LimitsVersion Support PolicySecuritySupportTrust & ComplianceChangelog
powered by Zudoku
Testing

Test preview environments

A preview environment is a full Zuplo deployment of a branch, on the same edge network as production, at its own URL. That makes it the highest-fidelity place to run your test suite before a change merges — closer to production than any local server, and without the queueing and drift of a shared staging environment.

Because zuplo test takes the target as a flag, the files you run against http://localhost:9000 are the files you run against the preview URL. Nothing in the suite changes.

How branches become environments

Push a branch to a connected repository and Zuplo deploys it:

  • The repository's default branch deploys to Production.
  • Every other branch deploys to a Preview environment with its own URL.

For the full mapping, see branch-based deployments. For how preview environments differ from working copies, see environments.

Get the URL into your tests

Preview URLs are derived from the branch name and project, so hard-coding one is a maintenance problem. Read the URL from the environment instead.

From the Zuplo GitHub integration

The integration reports a GitHub Deployment for each build, and the deployment status carries the environment URL. In a workflow triggered by the deployment_status event, that value is github.event.deployment_status.environment_url. This is the mechanism used in testing GitHub deployments, and it is the approach to prefer: no URL construction, and the tests cannot start before the deployment exists.

From your own pipeline

If you deploy from your own CI with zuplo deploy, capture the URL from the deploy command's output and pass it through:

TerminalCode
OUTPUT=$(npx zuplo deploy --api-key "$ZUPLO_API_KEY" --environment "$BRANCH" 2>&1) echo "$OUTPUT" DEPLOY_URL=$(echo "$OUTPUT" | grep -oP 'Deployed to \K(https://[^ ]+)') npx zuplo test --endpoint "$DEPLOY_URL"

For the complete workflow, see GitHub Actions: deploy and test. For pipeline patterns for other providers, see custom CI/CD.

Wait for the environment before testing

A deployment reporting success is not the same as a gateway serving traffic, and the gap between the two is the single most common cause of "flaky" gateway tests. The first few requests fail, the run is retried, and the real problem — a race in the pipeline — is filed as test flakiness.

Poll a cheap unauthenticated route with a hard deadline instead of sleeping:

TerminalCode
deadline=$((SECONDS + 120)) until curl --fail --silent --output /dev/null "$API_URL/health"; do if ((SECONDS >= deadline)); then echo "Gateway at $API_URL not ready after 120s" >&2 exit 1 fi sleep 2 done npx zuplo test --endpoint "$API_URL"

If your gateway has no health route, add one. See health checks.

Per-environment services and secrets

Preview environments have their own configuration, and a test that passes locally can fail on a preview for reasons that have nothing to do with your change:

  • Environment variables. Values are set per environment in the Zuplo Portal. A variable that exists in production but not on the preview is a real defect the preview run catches — but assert on the behavior, not on the variable.
  • API key buckets. API key authentication is backed by a bucket tied to the environment. Keys minted for one environment do not authenticate against another, so CI needs a fixture key for the environment it is testing.
  • Rate limit buckets. Rate limit state is per environment too. This works in your favor: a preview environment's limits are not being consumed by production traffic, which is part of what makes the rate limit recipe deterministic.

Keep fixture credentials in your CI provider's secret store and pass them to zuplo test as environment variables. Inside the test they are available on TestHelper.environment:

TerminalCode
TENANT_A_JWT="$PREVIEW_TENANT_A_JWT" npx zuplo test --endpoint "$API_URL"

Scope what runs where

The same files can run everywhere, but that does not mean every test runs everywhere:

TargetWhat to run
http://localhost:9000Everything. Fast feedback while editing.
Preview deploymentEverything. This is the run that gates the merge.
ProductionA small, read-only smoke subset selected with --filter.

Name the production-safe tests consistently — a smoke: prefix works well — and select them by name:

TerminalCode
npx zuplo test --endpoint https://api.example.com --filter "smoke"

Nothing with side effects belongs in that subset. See gateway test recipes for the test data hygiene rules that make this safe.

Clean up preview environments

Preview environments outlive the branch unless something removes them. Delete the branch and the environment goes with it when you use the GitHub integration. If you deploy from your own pipeline, add an explicit cleanup step on branch delete. See cleanup on branch delete.

Related

  • Get started with zuplo test
  • Gateway test recipes
  • Testing GitHub deployments
  • Environments
Edit this page
Last modified on August 21, 2026
Test recipesTest deployments
On this page
  • How branches become environments
  • Get the URL into your tests
    • From the Zuplo GitHub integration
    • From your own pipeline
  • Wait for the environment before testing
  • Per-environment services and secrets
  • Scope what runs where
  • Clean up preview environments
  • Related