Testing conventions and in-memory databases

**When to use:** Writing or debugging tests, choosing unit vs integration style, Postgres/ClickHouse tests, regenerating ClickHouse test schema, or **exporting test helpers from packages** without pulling test code into production bundles.

3,940 stars

Best use case

Testing conventions and in-memory databases is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

**When to use:** Writing or debugging tests, choosing unit vs integration style, Postgres/ClickHouse tests, regenerating ClickHouse test schema, or **exporting test helpers from packages** without pulling test code into production bundles.

Teams using Testing conventions and in-memory databases should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/testing/SKILL.md --create-dirs "https://raw.githubusercontent.com/latitude-dev/latitude-llm/main/.agents/skills/testing/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/testing/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How Testing conventions and in-memory databases Compares

Feature / AgentTesting conventions and in-memory databasesStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

**When to use:** Writing or debugging tests, choosing unit vs integration style, Postgres/ClickHouse tests, regenerating ClickHouse test schema, or **exporting test helpers from packages** without pulling test code into production bundles.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# Testing conventions and in-memory databases

**When to use:** Writing or debugging tests, choosing unit vs integration style, Postgres/ClickHouse tests, regenerating ClickHouse test schema, or **exporting test helpers from packages** without pulling test code into production bundles.

## Package exports (test code isolation)

Test utilities (fakes, in-memory DB helpers, fixtures) must **not** be exported from a package’s main entry (`src/index.ts`).

- **Never** re-export from `./test/` or `./testing/` in the main `src/index.ts`
- To expose test helpers, add a **`/testing` subpath** in `package.json` `exports`:

```json
{
  "exports": {
    ".": "./src/index.ts",
    "./testing": "./src/testing/my-test-helpers.ts"
  }
}
```

- Consumers: `import { Fake } from "@platform/my-package/testing"`
- Biome `noRestrictedImports` blocks test paths in production source; tsup fails the build if test code is resolved from prod entry points

## Conventions

- Shared default environment: Node with globals enabled (`packages/vitest-config/index.ts`)
- Write tests, mostly e2e, some unit tests when logic is complex
- **Unit tests**: domain entities/use-cases/policies with fakes
- **Contract tests**: adapter compliance against domain ports
- **Integration tests**: infra-backed tests for Postgres/ClickHouse/Redis/BullMQ/object storage
- **End-to-end tests**: ingest boundary to query boundary across organization scoping
- Keep tests deterministic and isolated
- Prefer package-local runs during iteration; run full monorepo tests before PR

## Database testing (in-memory)

**Always use in-memory databases for tests.** Do not use `vi.mock`/`vi.fn` to mock repository methods and do not require running database servers. The project provides embedded, in-process database engines that run the real SQL against the real schema:

- **ClickHouse → chdb** (`chdb` package): An in-process ClickHouse engine via `@platform/testkit`.
- **Postgres → PGlite** (`@electric-sql/pglite`): An in-process Postgres via WASM via `@platform/testkit`.

### Postgres test setup (`@platform/testkit`)

```typescript
import { setupTestPostgres } from "@platform/testkit"
import { beforeAll, describe, it } from "vitest"

const pg = setupTestPostgres()

describe("MyRepository", () => {
  it("does something", async () => {
    // pg.postgresDb is a real Drizzle instance backed by PGlite in-memory
    // pg.db is the lower-level Drizzle/PGlite instance for direct queries
  })
})
```

`setupTestPostgres()` registers vitest hooks automatically:

- **beforeAll**: creates a PGlite instance, creates the `latitude_app` role, and runs all Drizzle migrations
- **afterAll**: closes the PGlite connection

### ClickHouse test setup (`@platform/testkit`)

```typescript
import { setupTestClickHouse } from "@platform/testkit"
import { beforeAll, describe, it } from "vitest"

const ch = setupTestClickHouse()

describe("MyRepository", () => {
  let repo: ReturnType<typeof createMyRepository>

  beforeAll(() => {
    repo = createMyRepository(ch.client)
  })

  it("does something", async () => {
    // ch.client is a real ClickHouseClient backed by chdb in-memory
  })
})
```

`setupTestClickHouse()` registers vitest hooks automatically:

- **beforeAll**: creates a chdb session and loads the schema from `schema.sql`
- **beforeEach**: truncates all tables for test isolation
- **afterAll**: destroys the session and cleans up temp files

After new ClickHouse migrations, regenerate the in-memory test schema (only if the user asked you to run migration-related commands — see [database-clickhouse-weaviate](../database-clickhouse-weaviate/SKILL.md)):

```bash
pnpm --filter @platform/db-clickhouse ch:schema:dump
```

## Why not `vi.mock`?

Mocking repositories with `vi.fn()` tests the wiring, not the queries. In-memory databases catch real bugs: wrong column names, broken `argMax` aggregations, incorrect `GROUP BY` clauses, and schema mismatches. They run quickly with zero external dependencies.

Related Skills

testing

3940
from latitude-dev/latitude-llm

Writing or debugging tests, choosing unit vs integration style, Postgres/ClickHouse tests, regenerating ClickHouse test schema, or exporting test helpers from packages without pulling test code into production bundles.

web-frontend

3940
from latitude-dev/latitude-llm

apps/web UI — routes, @repo/ui, TanStack Start server functions and collections, forms, Tailwind layout rules, design-system updates, and useEffect / useMountEffect policy.

toolchain-commands

3940
from latitude-dev/latitude-llm

Installing dependencies, running dev/build/test/lint, filtering packages, single-test runs, git hooks, preparing a clone (.env.development / .env.test), or Docker-backed local services and dev servers.

gh-issue

3940
from latitude-dev/latitude-llm

Create clear, actionable GitHub issues for bugs, features, and improvements. Issues are primarily consumed by LLMs, so optimize for agent readability and actionability.

env-configuration

3940
from latitude-dev/latitude-llm

Adding or reading env vars, updating .env.example, or validating config at startup with parseEnv / parseEnvOptional.

effect-and-errors

3940
from latitude-dev/latitude-llm

Composing Effect programs, domain errors, HttpError, repository error types, or error propagation at HTTP boundaries.

database-postgres

3940
from latitude-dev/latitude-llm

Drizzle schema, repositories, RLS, SqlClient wiring, Postgres migrations, psql / reset, or platform mappers (toDomain* / toInsertRow).

database-clickhouse-weaviate

3940
from latitude-dev/latitude-llm

ClickHouse queries, Goose migrations, chdb test schema, Weaviate collections/migrations, or telemetry storage paths.

code-style

3940
from latitude-dev/latitude-llm

Biome formatting, import style, strict TypeScript, naming (including React file names), or generated files.

authentication

3940
from latitude-dev/latitude-llm

Sessions, sign-in/sign-up flows, OAuth, magic links, or organization context on the session.

Web app frontend (`apps/web`)

3940
from latitude-dev/latitude-llm

**When to use:** `apps/web` UI — routes, `@repo/ui`, TanStack Start server functions and collections, forms, Tailwind layout rules, design-system updates, and **`useEffect` / `useMountEffect` policy**.

Toolchain, commands, and CI

3940
from latitude-dev/latitude-llm

**When to use:** Installing dependencies, running dev/build/test/lint, filtering packages, single-test runs, git hooks, preparing a clone (`.env.development` / `.env.test`), or **Docker-backed local services and dev servers**.