---
title: "Testing Strategies"
description: "Write tests that validate routing configuration and middleware behavior before deployment."
canonical_url: "https://vercel.com/academy/microfrontends-on-vercel/testing-strategies"
md_url: "https://vercel.com/academy/microfrontends-on-vercel/testing-strategies.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-04-11T13:39:50.362Z"
content_type: "lesson"
course: "microfrontends-on-vercel"
course_title: "Microfrontends on Vercel"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# Testing Strategies

# 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:

| Utility                            | Purpose                                      |
| ---------------------------------- | -------------------------------------------- |
| `validateRouting`                  | Verify paths route to correct apps           |
| `validateMiddlewareConfig`         | Ensure middleware matchers work with routing |
| `validateMiddlewareOnFlaggedPaths` | Test 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):

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

Create `apps/marketing/jest.config.js`:

```javascript title="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`:

```json title="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`:

```typescript title="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`:

```typescript title="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

```bash
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:

```typescript
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:

```json title="turbo.json" {7-9}
{
  "$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`:

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

Now `pnpm test` runs tests across all apps.

## Commit

```bash
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 Test        | Why                           |
| ------------------- | ----------------------------- |
| All known paths     | Ensure routing doesn't break  |
| Nested paths        | Verify wildcard patterns work |
| Edge cases (404s)   | Confirm fallback behavior     |
| Middleware matchers | Prevent matcher conflicts     |
| Feature flag paths  | Validate conditional routing  |

## What's Next

Debug headers and tracing for observing routing decisions in production.


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
