118 lines
12 KiB
Markdown
118 lines
12 KiB
Markdown
# @suaveplan/testing-integration - Core integration test infrastructure: ServiceFixture<T> interface, TestEnvironment, createIntegrationSetup() factory, HealthPoller, skipIfUnavailable() helper
|
|
|
|
## Summary
|
|
|
|
Core integration test infrastructure for Vitest: fixture lifecycle management, health polling, and the global-setup bridge.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [environment](./src/environment/test-environment.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [test-environment](./src/environment/test-environment.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [fixture](./src/fixture/service-fixture.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [service-fixture](./src/fixture/service-fixture.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [health-poller](./src/helpers/health-poller.md) — `HealthPoller` repeatedly calls a `ServiceFixture`'s `healthCheck()` method at a configurable interval until the servic…
|
|
- [skip-if-unavailable](./src/helpers/skip-if-unavailable.md) — `skipIfUnavailable` returns a `beforeAll`-compatible callback that marks the current test as skipped when the named ser…
|
|
- [create-integration-setup-internal](./src/internal/create-integration-setup-internal.md) — This module exposes `createIntegrationSetupWithInject()` — the dependency-injected core of the public `createIntegratio…
|
|
- [fixture-registry](./src/internal/fixture-registry.md) — This module exposes the module-level `fixtureRegistry` `Map<string, ServiceFixture<Record<string, unknown>>>` that brid…
|
|
- [skip-if-unavailable-internal](./src/internal/skip-if-unavailable-internal.md) — This module exposes `createSkipIfUnavailableWithInject()` — the dependency-injected core of the public `skipIfUnavailab…
|
|
- [create-integration-setup](./src/setup/create-integration-setup.md) — `createIntegrationSetup` is the primary entry point for wiring integration test fixtures into the Vitest global-setup l…
|
|
- [global-setup](./src/setup/global-setup.md) — `global-setup.ts` is the Vitest global-setup module that bridges the fixture registry populated by `createIntegrationSe…
|
|
<!-- end:auto-docs --> - [test-environment](./src/environment/test-environment.md) — <!-- begin:auto-docs --> _(no submodules)_- [fixture](./src/fixture/service-fixture.md) — <!-- begin:auto-docs --> _(no submodules)_- [service-fixture](./src/fixture/service-fixture.md) — <!-- begin:auto-docs --> _(no submodules)_- [health-poller](./src/helpers/health-poller.md) — `HealthPoller` repeatedly calls a `ServiceFixture`'s `healthCheck()` method at a configurable interval until the servic…
|
|
- [skip-if-unavailable](./src/helpers/skip-if-unavailable.md) — `skipIfUnavailable` returns a `beforeAll`-compatible callback that marks the current test as skipped when the named ser…
|
|
- [create-integration-setup-internal](./src/internal/create-integration-setup-internal.md) — This module exposes `createIntegrationSetupWithInject()` — the dependency-injected core of the public `createIntegratio…
|
|
- [fixture-registry](./src/internal/fixture-registry.md) — This module exposes the module-level `fixtureRegistry` `Map<string, ServiceFixture<Record<string, unknown>>>` that brid…
|
|
- [skip-if-unavailable-internal](./src/internal/skip-if-unavailable-internal.md) — This module exposes `createSkipIfUnavailableWithInject()` — the dependency-injected core of the public `skipIfUnavailab…
|
|
- [create-integration-setup](./src/setup/create-integration-setup.md) — `createIntegrationSetup` is the primary entry point for wiring integration test fixtures into the Vitest global-setup l…
|
|
- [global-setup](./src/setup/global-setup.md) — `global-setup.ts` is the Vitest global-setup module that bridges the fixture registry populated by `createIntegrationSe…
|
|
- [test-environment](./src/environment/test-environment.md) — <!-- begin:auto-docs --> _(no submodules)_- [fixture](./src/fixture/service-fixture.md) — <!-- begin:auto-docs --> _(no submodules)_- [service-fixture](./src/fixture/service-fixture.md) — <!-- begin:auto-docs --> _(no submodules)_- [health-poller](./src/helpers/health-poller.md) — `HealthPoller` repeatedly calls a `ServiceFixture`'s `healthCheck()` method at a configurable interval until the servic…
|
|
- [skip-if-unavailable](./src/helpers/skip-if-unavailable.md) — `skipIfUnavailable` returns a `beforeAll`-compatible callback that marks the current test as skipped when the named ser…
|
|
- [create-integration-setup-internal](./src/internal/create-integration-setup-internal.md) — This module exposes `createIntegrationSetupWithInject()` — the dependency-injected core of the public `createIntegratio…
|
|
- [fixture-registry](./src/internal/fixture-registry.md) — This module exposes the module-level `fixtureRegistry` `Map<string, ServiceFixture<Record<string, unknown>>>` that brid…
|
|
- [skip-if-unavailable-internal](./src/internal/skip-if-unavailable-internal.md) — This module exposes `createSkipIfUnavailableWithInject()` — the dependency-injected core of the public `skipIfUnavailab…
|
|
- [create-integration-setup](./src/setup/create-integration-setup.md) — `createIntegrationSetup` is the primary entry point for wiring integration test fixtures into the Vitest global-setup l…
|
|
- [global-setup](./src/setup/global-setup.md) — `global-setup.ts` is the Vitest global-setup module that bridges the fixture registry populated by `createIntegrationSe…
|
|
- [test-environment](./src/environment/test-environment.md) — <!-- begin:auto-docs --> _(no submodules)_- [fixture](./src/fixture/service-fixture.md) — <!-- begin:auto-docs --> _(no submodules)_- [service-fixture](./src/fixture/service-fixture.md) — <!-- begin:auto-docs --> _(no submodules)_- [health-poller](./src/helpers/health-poller.md) — `HealthPoller` repeatedly calls a `ServiceFixture`'s `healthCheck()` method at a configurable interval until the servic…
|
|
- [skip-if-unavailable](./src/helpers/skip-if-unavailable.md) — `skipIfUnavailable` returns a `beforeAll`-compatible callback that marks the current test as skipped when the named ser…
|
|
- [create-integration-setup-internal](./src/internal/create-integration-setup-internal.md) — This module exposes `createIntegrationSetupWithInject()` — the dependency-injected core of the public `createIntegratio…
|
|
- [fixture-registry](./src/internal/fixture-registry.md) — This module exposes the module-level `fixtureRegistry` `Map<string, ServiceFixture<Record<string, unknown>>>` that brid…
|
|
- [skip-if-unavailable-internal](./src/internal/skip-if-unavailable-internal.md) — This module exposes `createSkipIfUnavailableWithInject()` — the dependency-injected core of the public `skipIfUnavailab…
|
|
- [create-integration-setup](./src/setup/create-integration-setup.md) — `createIntegrationSetup` is the primary entry point for wiring integration test fixtures into the Vitest global-setup l…
|
|
- [global-setup](./src/setup/global-setup.md) — `global-setup.ts` is the Vitest global-setup module that bridges the fixture registry populated by `createIntegrationSe…
|
|
- [test-environment](./src/environment/test-environment.md) — <!-- begin:auto-docs --> _(no submodules)_- [fixture](./src/fixture/service-fixture.md) — <!-- begin:auto-docs --> _(no submodules)_ - [service-fixture](./src/fixture/service-fixture.md) — <!-- begin:auto-docs --> _(no submodules)_- [health-poller](./src/helpers/health-poller.md) — `HealthPoller` repeatedly calls a `ServiceFixture`'s `healthCheck()` method at a configurable interval until the servic…
|
|
- [skip-if-unavailable](./src/helpers/skip-if-unavailable.md) — `skipIfUnavailable` returns a `beforeAll`-compatible callback that marks the current test as skipped when the named ser…
|
|
- [create-integration-setup-internal](./src/internal/create-integration-setup-internal.md) — This module exposes `createIntegrationSetupWithInject()` — the dependency-injected core of the public `createIntegratio…
|
|
- [fixture-registry](./src/internal/fixture-registry.md) — This module exposes the module-level `fixtureRegistry` `Map<string, ServiceFixture<Record<string, unknown>>>` that brid…
|
|
- [skip-if-unavailable-internal](./src/internal/skip-if-unavailable-internal.md) — This module exposes `createSkipIfUnavailableWithInject()` — the dependency-injected core of the public `skipIfUnavailab…
|
|
- [create-integration-setup](./src/setup/create-integration-setup.md) — `createIntegrationSetup` is the primary entry point for wiring integration test fixtures into the Vitest global-setup l…
|
|
- [global-setup](./src/setup/global-setup.md) — `global-setup.ts` is the Vitest global-setup module that bridges the fixture registry populated by `createIntegrationSe…
|
|
|
|
## Quick Start
|
|
|
|
```ts
|
|
// fixtures/redis.ts
|
|
import type { ServiceFixture } from "@suaveplan/testing-integration/fixture/service-fixture";
|
|
|
|
export const redisFixture: ServiceFixture<{ url: string }> = {
|
|
name: "redis",
|
|
async start() {
|
|
// start your real Redis container or in-process server
|
|
return { url: "redis://localhost:6379" };
|
|
},
|
|
async stop() { /* stop it */ },
|
|
async healthCheck() { return true; },
|
|
};
|
|
|
|
// vitest.config.ts
|
|
import { defineConfig } from "vitest/config";
|
|
import { createIntegrationSetup } from "@suaveplan/testing-integration/setup/create-integration-setup";
|
|
import { redisFixture } from "./fixtures/redis.js";
|
|
|
|
const { globalSetup, inject } = createIntegrationSetup({ redis: redisFixture });
|
|
|
|
export default defineConfig({ test: { globalSetup: [globalSetup] } });
|
|
export { inject };
|
|
|
|
// redis.test.ts
|
|
import { beforeEach } from "vitest";
|
|
import { inject } from "../vitest.config.js";
|
|
import { skipIfUnavailable } from "@suaveplan/testing-integration/helpers/skip-if-unavailable";
|
|
|
|
beforeEach(skipIfUnavailable("redis"));
|
|
|
|
it("reads from redis", async () => {
|
|
const { url } = inject("redis"); // typed as { url: string }
|
|
// ...
|
|
});
|
|
```
|
|
|
|
## Module Reference
|
|
|
|
| Module | Purpose | Docs |
|
|
|---|---|---|
|
|
| `./fixture/service-fixture` | `ServiceFixture<TConfig>` interface + `InferConfig<F>` | [service-fixture.md](src/fixture/service-fixture.md) |
|
|
| `./helpers/health-poller` | `HealthPoller` + `TestEnvironmentError` | [health-poller.md](src/helpers/health-poller.md) |
|
|
| `./helpers/skip-if-unavailable` | `skipIfUnavailable()` + `_createSkipIfUnavailableWithInject()` | [skip-if-unavailable.md](src/helpers/skip-if-unavailable.md) |
|
|
| `./environment/test-environment` | `TestEnvironment` parallel fixture orchestrator | [test-environment.md](src/environment/test-environment.md) |
|
|
| `./setup/create-integration-setup` | `createIntegrationSetup()` factory + `_fixtureRegistry` | [create-integration-setup.md](src/setup/create-integration-setup.md) |
|
|
| `./setup/global-setup` | Vitest `setup`/`teardown` hooks (global-setup module) | [global-setup.md](src/setup/global-setup.md) |
|
|
|
|
## Environment Bridge
|
|
|
|
The package uses two `provide`/`inject` keys as an internal implementation detail:
|
|
|
|
| Key | Type | Description |
|
|
|---|---|---|
|
|
| `__integration_configs__` | `Record<string, Record<string, unknown>>` | Config objects keyed by fixture key, populated in global-setup. |
|
|
| `__integration_failed__` | `string[]` | Names of fixtures whose `start()` threw, used by `skipIfUnavailable`. |
|
|
|
|
Do not read these keys directly — use `inject(key)` from `createIntegrationSetup` for configs and `skipIfUnavailable(name)` for skip guards.
|
|
|
|
## Adding a New `testing-integration-<service>` Plugin
|
|
|
|
When creating a sibling fixture package (e.g. `@suaveplan/testing-integration-clickhouse`):
|
|
|
|
1. Mirror the `vite.config.ts` of an existing fixture (e.g. `testing-integration-redis`). The `build.rollupOptions.output` block MUST contain all three of `preserveModules: true`, `preserveModulesRoot: "src"`, **and `entryFileNames: "[name].js"`**. Without the third line, Vite's lib mode derives the entry filename from the package name and the consumer-facing `dist/index.js` is never written — the package will appear to build but fail to resolve from any sibling workspace.
|
|
2. Run `bun run check:fixture-resolves` from the repo root to verify the new package resolves. The repo-level CI gate `//#check:fixture-resolves` (in `turbo.json`) will fail otherwise.
|
|
|