Vercel Logo

Testing Strategies

Routing misconfigurations are the most common microfrontends problem. A wrong path pattern can send users to 404 pages. Tests catch these before deployment.

Outcome

Write routing validation tests using @vercel/microfrontends/next/testing utilities.

The Problem: Configuration Drift

As your application grows, routing changes:

  • New paths added to apps
  • Middleware matchers updated
  • Redirects added or removed

Without tests, these changes can break routing silently. A redirect in marketing that conflicts with a docs path? You won't know until users complain.

Testing Utilities

The @vercel/microfrontends package includes three test utilities:

UtilityPurpose
validateRoutingVerify paths route to correct apps
validateMiddlewareConfigEnsure middleware matchers work with routing
validateMiddlewareOnFlaggedPathsTest feature flag routing behavior

Fast Track

  1. Install Jest in the marketing app
  2. Write routing validation tests
  3. Add middleware configuration tests
  4. Run tests in CI

Hands-on Exercise 3.2

Add routing tests to the Acme Platform.

Part 1: Set Up Jest

Add Jest to the marketing app (where microfrontends.json lives):

cd apps/marketing
pnpm add -D jest @types/jest ts-jest

Create apps/marketing/jest.config.js:

apps/marketing/jest.config.js
/** @type {import('jest').Config} */
const config = {
  testEnvironment: "node",
  transform: {
    "^.+\\.tsx?$": ["ts-jest", { useESM: true }],
  },
  moduleNameMapper: {
    "^@/(.*)$": "<rootDir>/$1",
  },
  testMatch: ["**/__tests__/**/*.test.ts"],
};
 
module.exports = config;

Add test script to apps/marketing/package.json:

apps/marketing/package.json
{
  "scripts": {
    "dev": "next dev --port 3000",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "test": "jest"
  }
}

Part 2: Write Routing Tests

Create apps/marketing/__tests__/routing.test.ts:

apps/marketing/__tests__/routing.test.ts
/* @jest-environment node */
import { validateRouting } from "@vercel/microfrontends/next/testing";
 
describe("microfrontends routing", () => {
  const configPath = "./microfrontends.json";
 
  test("routes marketing paths to marketing app", () => {
    expect(() =>
      validateRouting(configPath, {
        marketing: ["/", "/pricing", "/about", "/contact"],
      })
    ).not.toThrow();
  });
 
  test("routes docs paths to docs app", () => {
    expect(() =>
      validateRouting(configPath, {
        docs: [
          "/docs",
          "/docs/getting-started",
          "/docs/api",
          "/docs/api/reference",
          "/docs/guides/setup",
        ],
      })
    ).not.toThrow();
  });
 
  test("routes dashboard paths to dashboard app", () => {
    expect(() =>
      validateRouting(configPath, {
        dashboard: [
          "/app",
          "/app/projects",
          "/app/projects/123",
          "/settings",
          "/settings/profile",
          "/settings/billing",
        ],
      })
    ).not.toThrow();
  });
 
  test("404 paths fall through to default app", () => {
    expect(() =>
      validateRouting(configPath, {
        marketing: ["/unknown-page", "/random/nested/path"],
      })
    ).not.toThrow();
  });
});

Part 3: Write Middleware Configuration Tests

Create apps/marketing/__tests__/middleware.test.ts:

apps/marketing/__tests__/middleware.test.ts
/* @jest-environment node */
import { validateMiddlewareConfig } from "@vercel/microfrontends/next/testing";
import { config as marketingMiddlewareConfig } from "../middleware";
 
describe("middleware configuration", () => {
  const configPath = "./microfrontends.json";
 
  test("marketing middleware config is compatible with microfrontends", () => {
    expect(() =>
      validateMiddlewareConfig(marketingMiddlewareConfig, configPath)
    ).not.toThrow();
  });
});

This test ensures your middleware's matcher configuration doesn't conflict with microfrontends routing.

Part 4: Run the Tests

cd apps/marketing
pnpm test

Expected output:

PASS  __tests__/routing.test.ts
  microfrontends routing
    ✓ routes marketing paths to marketing app (15 ms)
    ✓ routes docs paths to docs app (3 ms)
    ✓ routes dashboard paths to dashboard app (2 ms)
    ✓ 404 paths fall through to default app (2 ms)

PASS  __tests__/middleware.test.ts
  middleware configuration
    ✓ marketing middleware config is compatible with microfrontends (8 ms)

Test Suites: 2 passed, 2 total
Tests:       5 passed, 5 total

Catching Misconfigurations

What happens when routing is wrong?

Add a failing test to see the error:

test("EXAMPLE: this would catch a misconfiguration", () => {
  expect(() =>
    validateRouting("./microfrontends.json", {
      // Wrong! /docs should route to docs, not marketing
      marketing: ["/docs"],
    })
  ).toThrow();
});

The error message shows exactly what's wrong:

Error: Path "/docs" routes to "docs" but expected "marketing"

Adding Tests to CI

Update turbo.json to include tests:

turbo.json
{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "test": {
      "dependsOn": ["^build"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "lint": {
      "dependsOn": ["^lint"]
    }
  }
}

Add root-level test script to package.json:

package.json
{
  "scripts": {
    "dev": "turbo dev",
    "build": "turbo build",
    "test": "turbo test",
    "lint": "turbo lint"
  }
}

Now pnpm test runs tests across all apps.

Commit

git add -A
git commit -m "test: add microfrontends routing validation tests"

Done-When

  • Jest configured in marketing app
  • Routing tests pass for all three apps
  • Middleware configuration test passes
  • Tests can run via pnpm test from root

Test Coverage Strategy

What to TestWhy
All known pathsEnsure routing doesn't break
Nested pathsVerify wildcard patterns work
Edge cases (404s)Confirm fallback behavior
Middleware matchersPrevent matcher conflicts
Feature flag pathsValidate conditional routing

What's Next

Debug headers and tracing for observing routing decisions in production.