A guide for writing, debugging, and maintaining Vitest tests while optimizing performance.

Install

mkdir -p .claude/skills/testing && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/973" && unzip -o skill.zip -d .claude/skills/testing && rm skill.zip

Installs to .claude/skills/testing

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Vitest testing guide. Use when writing or updating tests, fixing failing tests, improving coverage, debugging test issues, or setting up mocks.
143 chars✓ has a “when” trigger
Intermediate

Key capabilities

  • Create unit tests for models and repositories
  • Configure mock objects using spyOn
  • Implement integration tests with database handles
  • Manage regression test suites for bug fixes
  • Optimize test execution across different test suites

How it works

Guides the generation of test files and mock setups according to LobeHub architecture, ensuring isolation and proper database separation.

Inputs & outputs

You give it
Test requirement or code bug report
You get back
Passing test suite with regression protection

When to use testing

  • Create unit tests for new repository models
  • Debug failing Vitest test suites
  • Configure mock objects using vi.spyOn
  • Optimize test execution time

About this skill

LobeHub Testing Guide

Quick Reference

Commands:

# Run specific test file
bunx vitest run --silent='passed-only' '[file-path]'

# Database package (client-db, PGlite — default, skips BM25/pg_search)
cd packages/database && bunx vitest run --silent='passed-only' '[file]'

# Database package (server-db, Postgres — BM25/pgvector parity, what CI measures coverage in)
cd packages/database && TEST_SERVER_DB=1 bunx vitest run --silent='passed-only' '[file]'

Never run bun run test - it runs all 3000+ tests (~10 minutes).

Database models/repositories: every new file under packages/database/src/models/** or src/repositories/** ships with a sibling __tests__/<name>.test.ts in the same PR. Use the real DB via getTestDB() (integration style), guard BM25/full-text-search blocks with describe.skipIf(!isServerDB), and always test user-isolation. See references/db-model-test.md for setup, schema gotchas, and the client-vs-server-db split.

Test Categories

CategoryLocationConfig
Webappsrc/**/*.test.ts(x)vitest.config.ts
Packagespackages/*/**/*.test.tspackages/*/vitest.config.ts
Desktopapps/desktop/**/*.test.tsapps/desktop/vitest.config.ts

Core Principles

  1. Prefer vi.spyOn over vi.mock - More targeted, easier to maintain
  2. Tests must pass type check - Run bun run type-check after writing tests
  3. After 1-2 failed fix attempts, stop and ask for help
  4. Test behavior, not implementation details
  5. Regression tests for bug fixes - After fixing a bug, add a regression test that fails before the fix and passes after, to prevent recurrence
  6. No new component tests - Only update existing React component tests. Complex logic should be extracted into hooks and tested there instead
  7. All source changes before any test changes - Complete all source file edits first, then update tests in a separate pass. Interleaving disrupts reasoning about the source changes, especially across many files

Basic Test Structure

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';

beforeEach(() => {
  vi.clearAllMocks();
});

afterEach(() => {
  vi.restoreAllMocks();
});

describe('ModuleName', () => {
  describe('functionName', () => {
    it('should handle normal case', () => {
      // Arrange → Act → Assert
    });
  });
});

Mock Patterns

// ✅ Spy on direct dependencies
vi.spyOn(messageService, 'createMessage').mockResolvedValue('id');

// ✅ Use vi.stubGlobal for browser APIs
vi.stubGlobal('Image', mockImage);
vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock');

// ❌ Avoid mocking entire modules globally
vi.mock('@/services/chat'); // Too broad

Detailed Guides

See references/ for specific testing scenarios:

  • Database Model testing: references/db-model-test.md
  • Electron IPC testing: references/electron-ipc-test.md
  • Zustand Store Action testing: references/zustand-store-action-test.md
  • Agent Runtime E2E testing: references/agent-runtime-e2e.md
  • Desktop Controller testing: references/desktop-controller-test.md

Fixing Failing Tests — Optimize or Delete?

When tests fail due to implementation changes (not bugs), evaluate before blindly fixing:

Keep & Fix (update test data/assertions)

  • Behavior tests: Tests that verify what the code does (output, side effects, user-visible behavior). Just update mock data formats or expected values.
    • Example: Tool data structure changed from { name } to { function: { name } } → update mock data
    • Example: Output format changed from Current date: YYYY-MM-DD to Current date: YYYY-MM-DD (TZ) → update expected string

Delete (over-specified, low value)

  • Param-forwarding tests: Tests that assert exact internal function call arguments (e.g., expect(internalFn).toHaveBeenCalledWith(expect.objectContaining({ exact params }))) — these break on every refactor and duplicate what behavior tests already cover.
  • Implementation-coupled tests: Tests that verify how the code works internally rather than what it produces. If a higher-level test already covers the same behavior, the low-level test adds maintenance cost without coverage gain.

Decision Checklist

  1. Does the test verify externally observable behavior (API response, DB write, rendered output)? → Keep
  2. Does the test only verify internal wiring (which function receives which params)? → Check if a behavior test already covers it. If yes → Delete
  3. Is the same behavior already tested at a higher integration level? → Delete the lower-level duplicate
  4. Would the test break again on the next routine refactor? → Consider raising to integration level or deleting

When Writing New Tests

  • Prefer integration-level assertions (verify final output) over white-box assertions (verify internal calls)
  • Use expect.objectContaining only for stable, public-facing contracts — not for internal param shapes that change with refactors
  • Mock at boundaries (DB, network, external services), not between internal modules

Common Issues

  1. Module pollution: Use vi.resetModules() when tests fail mysteriously
  2. Mock not working: Check setup position and use vi.clearAllMocks() in beforeEach
  3. Test data pollution: Clean database state in beforeEach/afterEach
  4. Async issues: Wrap state changes in act() for React hooks

When not to use it

  • For ad-hoc script-only testing
  • When full integration with the database is explicitly not desired

Prerequisites

vitestbun

Limitations

  • Cannot use full 3000+ test suite
  • Requires internal project structure for database models
  • Limited to Vitest framework

How it compares

It enforces strict testing patterns (spyOn over mock) and specific command-line usage to handle the large internal codebase size.

Compared to similar skills

testing side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
testing (this skill)52moReviewIntermediate
chrome-devtools417moReviewIntermediate
obsidian-local-dev-loop327dReviewIntermediate
dependency-upgrade265moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

drizzle

lobehub

Drizzle ORM schema and database guide. Use when working with database schemas (src/database/schemas/*), defining tables, creating migrations, or database model code. Triggers on Drizzle schema definition, database migrations, or ORM usage questions.

238873

zustand

lobehub

Zustand state management guide. Use when working with store code (src/store/**), implementing actions, managing state, or creating slices. Triggers on Zustand store development, state management questions, or action implementation.

113434

react

lobehub

React component development guide. Use when working with React components (.tsx files), creating UI, using @lobehub/ui components, implementing routing, or building frontend features. Triggers on React component creation, modification, layout implementation, or navigation tasks.

3480

typescript

lobehub

TypeScript code style and optimization guidelines. Use when writing TypeScript code (.ts, .tsx, .mts files), reviewing code quality, or implementing type-safe patterns. Triggers on TypeScript development, type safety questions, or code style discussions.

2877

project-overview

lobehub

Complete project architecture and structure guide. Use when exploring the codebase, understanding project organization, finding files, or needing comprehensive architectural context. Triggers on architecture questions, directory navigation, or project overview needs.

1548

linear

lobehub

Linear issue management guide. Use when working with Linear issues, creating issues, updating status, or adding comments. Triggers on Linear issue references (LOBE-xxx), issue tracking, or project management tasks. Requires Linear MCP tools to be available.

10117

You might also like

chrome-devtools

mrgoonie

Browser automation, debugging, and performance analysis using Puppeteer CLI scripts. Use for automating browsers, taking screenshots, analyzing performance, monitoring network traffic, web scraping, form automation, and JavaScript debugging.

41157

obsidian-local-dev-loop

jeremylongshore

Configure Obsidian plugin development with hot-reload and fast iteration. Use when setting up development workflow, configuring test vaults, or establishing a rapid development cycle. Trigger with phrases like "obsidian dev loop", "obsidian hot reload", "obsidian development workflow", "develop obsidian plugin".

328

dependency-upgrade

wshobson

Manage major dependency version upgrades with compatibility analysis, staged rollout, and comprehensive testing. Use when upgrading framework versions, updating major dependencies, or managing breaking changes in libraries.

26240

playwright-browser-automation

lackeyjb

Complete browser automation with Playwright. Auto-detects dev servers, writes clean test scripts to /tmp. Test pages, fill forms, take screenshots, check responsive design, validate UX, test login flows, check links, automate any browser task. Use when user wants to test websites, automate browser interactions, validate web functionality, or perform any browser-based testing.

29146

nestjs-expert

davila7

Nest.js framework expert specializing in module architecture, dependency injection, middleware, guards, interceptors, testing with Jest/Supertest, TypeORM/Mongoose integration, and Passport.js authentication. Use PROACTIVELY for any Nest.js application issues including architecture decisions, testing strategies, performance optimization, or debugging complex dependency injection problems. If a specialized expert is a better fit, I will recommend switching and stop.

3758

zod-4

prowler-cloud

Zod 4 schema validation patterns. Trigger: When creating or updating Zod v4 schemas for validation/parsing (forms, request payloads, adapters), including v3 -> v4 migration patterns.

1260

Search skills

Search the agent skills registry