Run oaths through vitest
This guide shows you how to run Varar oaths as part of a vitest suite instead of
(or alongside) the varar CLI — one runner, one watch mode, one CI job.
It assumes Varar is already set up in your repo. If not, start with Get started on your computer.
1. Install the adapter
Section titled “1. Install the adapter”pnpm add -D @varar/vitest vitestYour step definitions keep importing @varar/varar — never the adapter.
2. Wire the plugin into vitest
Section titled “2. Wire the plugin into vitest”In vitest.config.ts:
import vararPlugin from '@varar/vitest'import { VararResultsReporter } from '@varar/vitest/reporter'import { defineConfig } from 'vitest/config'
export default defineConfig({ plugins: [vararPlugin()], test: { reporters: ['default', new VararResultsReporter()], },})3. Let varar.config.json decide what is an oath
Section titled “3. Let varar.config.json decide what is an oath”The plugin reads varar.config.json and drives vitest’s own include/exclude
from it — you don’t repeat the globs in the vitest config:
{ "docs": { "include": ["varar/**/*.md"], "exclude": ["varar/drafts/**"] }, "steps": ["src/varar/**/*.steps.ts"]}A file is an oath iff it matches the docs.include globs (minus docs.exclude).
The same config is consulted by the varar CLI and the language server, so all
three always agree.
The plugin does this by replacing vitest’s test.include and test.exclude
(vitest’s default excludes, like node_modules, are kept). In a repo that also
has ordinary unit tests, scope the plugin to its own project so it doesn’t
clobber their globs:
export default defineConfig({ test: { projects: [ { test: { name: 'unit', include: ['src/**/*.test.ts'] } }, { plugins: [vararPlugin()], test: { name: 'oaths' } }, ], },})4. Run
Section titled “4. Run”npx vitest runYour .md oaths now appear as test files in vitest’s output, watch mode, and
CI reporting, next to your ordinary *.test.ts files.
Accept drift
Section titled “Accept drift”When a paragraph that used to be an example stops matching any step, the run fails as drift. Accepting it is one command — the same one every other port uses:
VARAR_UPDATE=1 npx vitest run # go green AND re-record varar.lock.jsonThe plugin never writes during a transform; the reporter records the baseline at the end of the run.
Commit the updated varar.lock.json — that is what makes the acknowledgment
visible in review.
Set-up and tear-down
Section titled “Set-up and tear-down”Varar has no lifecycle hooks of its own. Use vitest’s native beforeEach /
afterEach in a regular test-setup file for anything the oaths need around
them (databases, servers, fixtures).
Note that afterEach cannot see the example’s state: the state factory is
per-step-file and the value never leaves the run. Anything that needs tearing
down must also be reachable from outside the state — for example, have the
stimulus that creates it record it in module scope in the steps file, and tear
that down in afterEach.