Die Benutzeroberfläche ist lokalisiert; die Skill-Inhalte der ursprünglichen Autoren bleiben in ihrer Originalsprache, und einige Erläuterungsseiten sind auf Englisch verfügbar.
Skills entdecken
Entwicklung · SKILL.md

vitest

vitest

Vitest testing framework. Covers unit tests, mocking, and coverage. Use for testing Vite-based and Node.js projects. USE WHEN: user mentions "vitest", "vite test", "unit test", asks about "vi.fn", "vi.mock", "test coverage", "mock functions", "test vite project" DO NOT USE FOR: E2E tests - use `playwright` instead; React component testing - combine with `…

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill-Dokumentation

GitHub

name: vitest description: | Vitest testing framework. Covers unit tests, mocking, and coverage. Use for testing Vite-based and Node.js projects.

USE WHEN: user mentions "vitest", "vite test", "unit test", asks about "vi.fn", "vi.mock", "test coverage", "mock functions", "test vite project"

DO NOT USE FOR: E2E tests - use playwright instead; React component testing - combine with testing-library; Jest projects - use jest instead allowed-tools: Read, Grep, Glob, Write, Edit

Vitest Core Knowledge

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: vitest for comprehensive documentation.

When NOT to Use This Skill

  • E2E Testing - Use playwright or cypress for browser-based end-to-end tests
  • React Component Testing - Combine this skill with testing-library for component tests
  • Jest Migration - If project uses Jest, use jest skill instead (syntax is similar but not identical)
  • API Integration Tests - Use framework-specific integration test skills (spring-boot-integration, etc.)

Basic Test

import { describe, it, expect, beforeEach, vi } from 'vitest';
import { calculateTotal } from './utils';

describe('calculateTotal', () => {
  it('should sum array of numbers', () => {
    expect(calculateTotal([1, 2, 3])).toBe(6);
  });

  it('should return 0 for empty array', () => {
    expect(calculateTotal([])).toBe(0);
  });
});

Matchers

// Equality
expect(value).toBe(exact);
expect(value).toEqual(deepEqual);
expect(value).toMatchObject(partial);

// Truthiness
expect(value).toBeTruthy();
expect(value).toBeFalsy();
expect(value).toBeNull();
expect(value).toBeDefined();

// Numbers
expect(value).toBeGreaterThan(n);
expect(value).toBeCloseTo(0.3, 5);

// Strings
expect(str).toMatch(/pattern/);
expect(str).toContain('substring');

// Arrays
expect(arr).toContain(item);
expect(arr).toHaveLength(3);

// Errors
expect(() => fn()).toThrow();
expect(() => fn()).toThrowError('message');

Mocking

// Mock function
const mockFn = vi.fn();
mockFn.mockReturnValue(42);
mockFn.mockResolvedValue({ data: [] });

// Mock module
vi.mock('./api', () => ({
  fetchUsers: vi.fn().mockResolvedValue([])
}));

// Spy
const spy = vi.spyOn(object, 'method');
expect(spy).toHaveBeenCalledWith('arg');

// Reset
vi.clearAllMocks();
vi.resetAllMocks();

Async Tests

it('should fetch data', async () => {
  const data = await fetchUsers();
  expect(data).toHaveLength(3);
});

it('should reject', async () => {
  await expect(fetchFail()).rejects.toThrow('Error');
});

Config

// vitest.config.ts
export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
    coverage: { provider: 'v8', reporter: ['text', 'html'] }
  }
});

Production Readiness

Test Organization

// Proper test structure
describe('UserService', () => {
  // Setup/teardown at appropriate level
  let service: UserService;
  let mockDb: MockedObject<Database>;

  beforeAll(async () => {
    // Expensive setup once
    await setupTestDatabase();
  });

  beforeEach(() => {
    // Reset state before each test
    mockDb = vi.mocked(new Database());
    service = new UserService(mockDb);
    vi.clearAllMocks();
  });

  afterAll(async () => {
    // Cleanup
    await teardownTestDatabase();
  });

  describe('create', () => {
    it('should create user with valid data', async () => {
      // Arrange
      const input = { name: 'John', email: 'john@example.com' };
      mockDb.insert.mockResolvedValue({ id: '1', ...input });

      // Act
      const result = await service.create(input);

      // Assert
      expect(result).toMatchObject(input);
      expect(mockDb.insert).toHaveBeenCalledWith('users', input);
    });

    it('should throw on duplicate email', async () => {
      mockDb.insert.mockRejectedValue(new UniqueConstraintError());
      await expect(service.create(input)).rejects.toThrow('Email already exists');
    });
  });
});

Coverage Configuration

// vitest.config.ts
export default defineConfig({
  test: {
    coverage: {
      provider: 'v8',
      reporter: ['text', 'html', 'lcov'],
      exclude: [
        'node_modules/',
        'test/',
        '**/*.d.ts',
        '**/*.config.*',
        '**/types/**',
      ],
      thresholds: {
        lines: 80,
        functions: 80,
        branches: 75,
        statements: 80,
      },
    },
  },
});

CI Configuration

# GitHub Actions
- name: Run tests
  run: npm run test:ci

- name: Upload coverage
  uses: codecov/codecov-action@v3
  with:
    files: ./coverage/lcov.info
    fail_ci_if_error: true
// package.json scripts
{
  "scripts": {
    "test": "vitest",
    "test:ci": "vitest run --coverage --reporter=junit --outputFile=test-results.xml",
    "test:watch": "vitest --watch"
  }
}

Monitoring Metrics

MetricTarget
Line coverage> 80%
Branch coverage> 75%
Test execution time< 60s
Flaky test rate0%

Checklist

  • Arrange-Act-Assert pattern
  • Isolated tests (no shared state)
  • Meaningful test descriptions
  • Coverage thresholds enforced
  • CI/CD integration
  • No console.log in tests
  • Mocks reset between tests
  • Async tests properly awaited
  • Edge cases covered
  • Error paths tested

Anti-Patterns

Anti-PatternWhy It's BadSolution
Testing implementation detailsTests break on refactorTest behavior, not internals
Sharing state between testsFlaky, order-dependent testsUse beforeEach, isolated setup
Arbitrary waits (setTimeout)Slow, unreliable testsUse waitFor or async utilities
Not resetting mocksPrevious test affects nextvi.clearAllMocks() in beforeEach
Testing private methodsTight coupling to implementationTest through public API
One giant testHard to debug failuresOne assertion per test (ideally)
No error case testsProduction bugs slip throughTest happy path AND error paths

Quick Troubleshooting

ProblemLikely CauseSolution
"Cannot find module"Missing mock setupCheck vi.mock() path matches import
Test timeoutAsync not awaitedEnsure all async operations use await
"Expected 0 calls, received 1"Mock not clearedAdd vi.clearAllMocks() in beforeEach
Flaky testsShared state or timingIsolate setup, avoid setTimeout
Coverage not updatingCache issueRun with --no-cache flag
"TypeError: vi.fn is not a function"Missing importImport { vi } from 'vitest'

Reference Documentation

Gespeicherte Skills