How to Test OmniRoute Implementation: Unit, Vitest, and Integration Testing Guide

OmniRoute validates its AI gateway through a three-layer testing strategy—Unit tests for isolated logic, Vitest for streaming engines, and Integration/E2E tests for full request pipelines—that ensures correctness across Zod schemas, combo routing strategies, and provider resilience.

Testing a multi-provider LLM gateway requires verifying everything from pure function logic to complex failover behavior across network boundaries. This guide explains how to test OmniRoute implementation using the repository's comprehensive test architecture, which splits validation across Node's native test runner, high-performance Vitest suites, and full-stack integration scenarios. Whether you're validating a new combo routing strategy in chatCore.ts or ensuring streaming resilience, OmniRoute's test harnesses provide the isolated environments and mocking utilities required for reliable continuous integration.

OmniRoute's Three-Layer Testing Architecture

The repository organizes verification into three complementary layers, each targeting different aspects of the gateway's behavior.

Unit tests validate isolated functions, Zod schemas, and pure-logic modules using Node's native test runner. Execute these with:

npm run test:unit

Vitest tests exercise the streaming engine, combo routing algorithms, and MCP tools using the fast Vitest runner focused on the open-sse workspace. Run these with:

npm run test:vitest

Integration and E2E tests spin up the Next.js server (or MCP server) and execute end-to-end scenarios against real provider mocks. This layer includes live WebSocket tests, proxy health checks, and UI smoke tests via Playwright. Execute with:

npm run test:integration
npm run test:e2e

All test commands enforce the repository's quality-gate rules, failing CI on any regression.

The Chat Pipeline Harness for Isolated Integration Testing

All integration tests build upon a Chat Pipeline Harness defined in tests/integration/_chatPipelineHarness.ts. This harness wires together the request-validation, routing, and response-generation code paths without requiring live network access.

The harness creates an in-memory SQLite database, seeds provider connections, and patches globalThis.fetch with mock responses. This isolates tests from external network calls while still exercising the full request pipeline defined in open-sse/handlers/chatCore.ts.

Import and initialize the harness in any integration test:

import { createChatPipelineHarness } from "./_chatPipelineHarness.ts";

const harness = await createChatPipelineHarness("combo-routing");

The harness leverages call-logging helpers from src/lib/usage/callLogs.ts to capture request metadata for assertions.

Testing Combo Routing Strategies with the Priority Pattern

The following example from tests/integration/combo-routing-e2e.test.ts demonstrates how to verify a priority combo strategy that sticks to the primary model while healthy:

test("priority combo sticks to the primary model while healthy", async () => {
  await seedConnection("openai", { apiKey: "sk-openai-priority" });
  await seedConnection("claude", { apiKey: "sk-claude-priority" });
  await combosDb.createCombo({
    name: "router-priority-healthy",
    strategy: "priority",
    models: ["openai/gpt-4o-mini", "claude/claude-3-5-sonnet-20241022"],
  });

  const seenTargets = [];
  globalThis.fetch = async (url) => {
    seenTargets.push(String(url));
    return buildOpenAIResponse("Primary stayed active");
  };

  const first = await handleChat(
    buildRequest({ body: buildOpenAIChatBody("router-priority-healthy", "Route priority first") })
  );
  const second = await handleChat(
    buildRequest({ body: buildOpenAIChatBody("router-priority-healthy", "Route priority second") })
  );

  assert.equal(first.status, 200);
  assert.equal(second.status, 200);
  assert.equal(seenTargets.length, 2);
  assert.ok(seenTargets.every((t) => t.includes("/chat/completions")));
});

This test validates:

  • Connection seeding: Populates provider tables via seedConnection
  • Combo creation: Verifies the combo DB schema through combosDb.createCombo
  • Routing logic: Exercises the priority strategy inside handleChat (located in open-sse/handlers/chatCore.ts)
  • Fallback behavior: Confirms primary model usage when mocks return successful responses
  • Response validation: Asserts HTTP status codes and upstream call counts

Similar integration tests exist for round-robin, fallback-on-error, and sticky-round-robin strategies within the tests/integration/ directory.

Running the Complete Test Suite

Execute the full verification workflow using npm scripts. First, install dependencies and initialize environment variables:

npm ci

Run specific test layers:


# Unit tests only

npm run test:unit

# Vitest suite (streaming, combo, MCP)

npm run test:vitest

# Integration tests (requires server spin-up)

npm run test:integration

# UI end-to-end tests with Playwright

npm run test:e2e

Verify coverage thresholds, which must remain at or above 60% across all metrics:

npm run test:coverage

Coverage regressions will abort the CI pipeline and must be resolved before merging.

Debugging Failed Tests and Network Safety

When tests fail, the harness automatically prints the captured fetchCalls array and full request/response objects. Enable verbose logging for detailed trace output:

OMNIROUTE_LOG_LEVEL=debug npm run test:integration

Logging configuration resides in src/sse/utils/logger.ts.

OmniRoute prevents accidental live network calls during testing through the outbound SSRF guard implemented in src/shared/network/outboundUrlGuard.ts. To temporarily disable this guard for a specific test requiring real provider access, set the environment variable in the test's beforeEach hook:

beforeEach(() => {
  process.env.OUTBOUND_SSRF_GUARD_ENABLED = "0";
});

Continuous Integration Quality Gates

The CI pipeline executes a strict four-step sequence on every push to ensure code quality:

  1. npm run lint — ESLint with strict no-eval and no-explicit-any rules
  2. npm run check:docs-all — Validates generated documentation consistency
  3. npm run test:unit + npm run test:vitest — Ensures core logic and streaming engines pass
  4. npm run test:coverage — Enforces the 60% coverage gate

Failure at any stage blocks PR merging until resolved.

Summary

  • OmniRoute implements a three-layer testing strategy (Unit, Vitest, Integration/E2E) to validate logic, streaming engines, and full pipelines.
  • The Chat Pipeline Harness in tests/integration/_chatPipelineHarness.ts provides isolated in-memory database and fetch mocking for integration tests.
  • Combo routing strategies like priority and round-robin are tested against mocked provider responses in tests/integration/combo-routing-e2e.test.ts.
  • All test commands respect 60% coverage thresholds and strict quality gates that block CI on failure.
  • The SSR guard (src/shared/network/outboundUrlGuard.ts) prevents accidental live network calls, with debug logging available via OMNIROUTE_LOG_LEVEL=debug.

Frequently Asked Questions

What is the Chat Pipeline Harness in OmniRoute?

The Chat Pipeline Harness is a test utility located in tests/integration/_chatPipelineHarness.ts that creates an isolated testing environment for integration tests. It initializes an in-memory SQLite database, seeds provider connection tables, and patches globalThis.fetch to intercept outbound requests. This allows developers to test the complete request pipeline—including routing logic in chatCore.ts—without making real network calls to LLM providers.

How do I run only the unit tests for OmniRoute?

Execute npm run test:unit to run only the unit test suite. This command uses Node's native test runner to validate isolated functions, Zod schemas, and pure-logic modules without spinning up servers or databases. Unit tests complete quickly and are ideal for rapid feedback during development iterations.

What code coverage threshold does OmniRoute enforce?

OmniRoute enforces a minimum 60% coverage threshold across all metrics including statements, branches, functions, and lines. The npm run test:coverage command validates these thresholds, and any regression will fail the CI pipeline. This gate ensures that new features include adequate test coverage before merging into the main branch.

How can I debug a failing combo routing test?

Set the environment variable OMNIROUTE_LOG_LEVEL=debug before running the test suite to enable verbose logging from src/sse/utils/logger.ts. The Chat Pipeline Harness automatically captures the fetchCalls array and prints full request/response objects upon assertion failure. For tests requiring real provider validation, temporarily disable the SSRF guard by setting process.env.OUTBOUND_SSRF_GUARD_ENABLED = "0" in your test's beforeEach hook.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →