openclaw - 💡(How to fix) Fix Testing: Consolidate multiple Vitest config files into unified configuration [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#59730Fetched 2026-04-08 02:41:17
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Author
Participants

Code Example

vitest.config.ts              # base config
vitest.unit.config.ts         # extends base with unit test settings
vitest.e2e.config.ts          # extends base with E2E settings
vitest.extensions.config.ts   # for extension tests
vitest.contracts.config.ts  # for contract tests
vitest.gateway.config.ts      # for gateway tests

---

import { defineConfig } from "vitest/config";
import baseConfig from "./vitest.config.ts";
import { loadPatternListFromEnv } from "./vitest.pattern-file.ts";
import { resolveVitestIsolation } from "./vitest.scoped-config.ts";
import {
  unitTestAdditionalExcludePatterns,
  unitTestIncludePatterns,
} from "./vitest.unit-paths.mjs";

// ... complex merge logic for includes/excludes

---

// vitest.config.ts
import { defineConfig } from "vitest/config";

const mode = process.env.VITEST_MODE || "unit";

const modeConfigs = {
  unit: {
    include: ["src/**/*.test.ts"],
    exclude: ["**/*.e2e.test.ts", "**/*.live.test.ts"],
    isolate: true,
  },
  e2e: {
    include: ["**/*.e2e.test.ts"],
    exclude: [],
    isolate: false,
  },
  extensions: {
    include: ["extensions/**/*.test.ts"],
    // ...
  },
  // ... other modes
};

export default defineConfig({
  test: modeConfigs[mode] || modeConfigs.unit,
});

---

# Instead of: pnpm vitest --config vitest.e2e.config.ts
VITEST_MODE=e2e pnpm vitest

# Or add package.json scripts:
# "test:e2e": "VITEST_MODE=e2e vitest"

---

// vitest.config.ts
import { defineConfig } from "vitest/config";

export function createConfig(mode: "unit" | "e2e" | "extensions") {
  const configs = { /* ... */ };
  return defineConfig(configs[mode]);
}

export default createConfig("unit");
RAW_BUFFERClick to expand / collapse

Problem

OpenClaw currently maintains 6+ separate Vitest configuration files with complex inheritance patterns:

vitest.config.ts              # base config
vitest.unit.config.ts         # extends base with unit test settings
vitest.e2e.config.ts          # extends base with E2E settings
vitest.extensions.config.ts   # for extension tests
vitest.contracts.config.ts  # for contract tests
vitest.gateway.config.ts      # for gateway tests

Each imports shared utilities and adds environment-specific behavior, creating a maintenance burden.

Current Complexity

From vitest.unit.config.ts:

import { defineConfig } from "vitest/config";
import baseConfig from "./vitest.config.ts";
import { loadPatternListFromEnv } from "./vitest.pattern-file.ts";
import { resolveVitestIsolation } from "./vitest.scoped-config.ts";
import {
  unitTestAdditionalExcludePatterns,
  unitTestIncludePatterns,
} from "./vitest.unit-paths.mjs";

// ... complex merge logic for includes/excludes

Issues:

  1. Cognitive overhead — Contributors must understand the inheritance chain
  2. Duplicated logic — Each config repeats similar environment variable handling
  3. Discovery difficulty — Unclear which config to use for what purpose
  4. Conditional complexity — Environment-based loading scattered across files

Proposed Solution

Option A: Single Config with Mode Flags (Recommended)

Consolidate to vitest.config.ts that uses process.env.VITEST_MODE:

// vitest.config.ts
import { defineConfig } from "vitest/config";

const mode = process.env.VITEST_MODE || "unit";

const modeConfigs = {
  unit: {
    include: ["src/**/*.test.ts"],
    exclude: ["**/*.e2e.test.ts", "**/*.live.test.ts"],
    isolate: true,
  },
  e2e: {
    include: ["**/*.e2e.test.ts"],
    exclude: [],
    isolate: false,
  },
  extensions: {
    include: ["extensions/**/*.test.ts"],
    // ...
  },
  // ... other modes
};

export default defineConfig({
  test: modeConfigs[mode] || modeConfigs.unit,
});

Usage:

# Instead of: pnpm vitest --config vitest.e2e.config.ts
VITEST_MODE=e2e pnpm vitest

# Or add package.json scripts:
# "test:e2e": "VITEST_MODE=e2e vitest"

Option B: Factory Function Pattern

// vitest.config.ts
import { defineConfig } from "vitest/config";

export function createConfig(mode: "unit" | "e2e" | "extensions") {
  const configs = { /* ... */ };
  return defineConfig(configs[mode]);
}

export default createConfig("unit");

Migration Plan

  1. Create unified vitest.config.ts with mode support
  2. Update package.json scripts to use VITEST_MODE instead of --config
  3. Update CI workflows
  4. Delete old config files after verification
  5. Document the pattern in docs/development/testing.md

Acceptance Criteria

  • Single vitest.config.ts supports all test modes
  • package.json scripts updated
  • All CI workflows pass
  • Documentation added explaining VITEST_MODE
  • Old config files removed

References

  • Current configs: vitest.*.config.ts
  • Related: scripts/test-parallel.mjs, CI workflows

Priority: High Effort: Low (1 day) Labels: testing, refactor, dx

extent analysis

TL;DR

Consolidate Vitest configuration files into a single file using a mode flag or factory function pattern to reduce cognitive overhead and duplicated logic.

Guidance

  • Identify the most suitable approach between using a mode flag (VITEST_MODE) or a factory function pattern based on the project's specific needs and existing configuration complexity.
  • Update package.json scripts to utilize the chosen approach, replacing the need for multiple configuration files.
  • Verify that all test modes are supported and functional with the new unified configuration before removing old config files.
  • Document the new pattern in the project's documentation to ensure contributors understand the updated testing configuration.

Example

// vitest.config.ts (mode flag example)
import { defineConfig } from "vitest/config";

const mode = process.env.VITEST_MODE || "unit";

const modeConfigs = {
  unit: {
    include: ["src/**/*.test.ts"],
    exclude: ["**/*.e2e.test.ts", "**/*.live.test.ts"],
    isolate: true,
  },
  // ... other modes
};

export default defineConfig({
  test: modeConfigs[mode] || modeConfigs.unit,
});

Notes

The choice between the mode flag and factory function pattern should be based on the project's specific requirements and the complexity of the existing configurations. Both approaches aim to simplify the configuration but may have different implications for the project's structure and maintainability.

Recommendation

Apply the mode flag approach (VITEST_MODE) as it seems to be the recommended solution in the issue, offering a straightforward way to manage different test modes through environment variables.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING