Vitest is not just a fast test runner — it has a rich programmatic API that lets you run tests, collect coverage, and build custom testing tools. Here's what you're missing.
Programmatic API — Run Tests from Code
Vitest exposes a Node.js API for running tests programmatically:
import { startVitest } from "vitest/node"
const vitest = await startVitest("test", [], {
watch: false,
reporters: ["verbose"],
coverage: {
enabled: true,
provider: "v8"
}
})
const results = vitest.state.getFiles()
for (const file of results) {
console.log(`${file.name}: ${file.result?.state}`)
for (const task of file.tasks) {
console.log(` ${task.name}: ${task.result?.state}`)
}
}
await vitest.close()
Custom Reporters
Build custom reporters to process test results:
// custom-reporter.js
export default class SlackReporter {
onInit(ctx) {
this.startTime = Date.now()
this.results = []
}
onFinished(files, errors) {
const duration = Date.now() - this.startTime
const passed = files.filter(f => f.result?.state === "pass").length
const failed = files.filter(f => f.result?.state === "fail").length
const message = [
`Test Results (${duration}ms)`,
`Passed: ${passed} | Failed: ${failed}`,
...errors.map(e => `Error: ${e.message}`)
].join("\n")
// Send to Slack, email, etc.
fetch(process.env.SLACK_WEBHOOK, {
method: "POST",
body: JSON.stringify({ text: message })
})
}
}
// vitest.config.js
export default {
test: {
reporters: ["default", "./custom-reporter.js"]
}
}
Browser Mode API
Run tests in a real browser:
// vitest.config.js
import { defineConfig } from "vitest/config"
export default defineConfig({
test: {
browser: {
enabled: true,
name: "chromium",
provider: "playwright"
}
}
})
// tests/dom.test.js
import { expect, test } from "vitest"
import { render, screen } from "@testing-library/react"
import App from "../src/App"
test("renders in real browser", async () => {
render(<App />)
expect(screen.getByText("Hello World")).toBeInTheDocument()
})
Workspace API — Monorepo Testing
Test multiple projects with different configs:
// vitest.workspace.js
export default [
{
test: {
name: "unit",
include: ["src/**/*.test.ts"],
environment: "node"
}
},
{
test: {
name: "integration",
include: ["tests/**/*.test.ts"],
environment: "jsdom",
setupFiles: ["./tests/setup.ts"]
}
},
{
test: {
name: "e2e",
include: ["e2e/**/*.test.ts"],
browser: { enabled: true, name: "chromium", provider: "playwright" }
}
}
]
Snapshot API
Custom snapshot serializers:
// vitest.config.js
export default {
test: {
snapshotSerializers: ["./html-serializer.js"]
}
}
// html-serializer.js
export default {
serialize(val) {
return val.outerHTML
.replace(/ data-testid="[^"]*"/g, "")
.replace(/ class="[^"]*"/g, "")
},
test(val) {
return val instanceof HTMLElement
}
}
Type Testing
Test your TypeScript types:
import { expectTypeOf, test } from "vitest"
import { mount } from "../src/mount"
test("mount returns correct type", () => {
expectTypeOf(mount).toBeFunction()
expectTypeOf(mount).parameter(0).toMatchTypeOf<{ component: any }>()
expectTypeOf(mount).returns.toHaveProperty("unmount")
})
Key Takeaways
- Programmatic API lets you run tests from Node.js code
- Custom Reporters for Slack, email, CI integration
- Browser Mode runs tests in real Chromium/Firefox/WebKit
- Workspace manages monorepo test configurations
- Snapshot serializers customize snapshot output
- Type testing validates TypeScript types
See Vitest docs for the complete API reference.
Building web scrapers or data pipelines? Check out my Apify actors for ready-made solutions, or email spinov001@gmail.com for custom development.
Top comments (0)