npx skills add https://github.com/jezweb/claude-skills --skill vitest状态 : 生产就绪 最后更新 : 2026-02-06 Vitest 版本 : 4.x Vite 兼容性 : 6.x
# 安装
pnpm add -D vitest
# 添加到 package.json
{
"scripts": {
"test": "vitest",
"test:run": "vitest run",
"test:coverage": "vitest run --coverage"
}
}
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
environment: 'node',
},
});
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['./src/test/setup.ts'],
css: true,
},
});
import { defineConfig } from 'vitest/config';
import { cloudflare } from '@cloudflare/vite-plugin';
export default defineConfig({
plugins: [cloudflare()],
test: {
globals: true,
environment: 'node',
// Workers 测试通常需要更长的超时时间来处理 D1/KV
testTimeout: 10000,
},
});
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
import { vi, describe, it, expect } from 'vitest';
import { fetchUser } from './api';
// 模拟整个模块
vi.mock('./api', () => ({
fetchUser: vi.fn(),
}));
describe('用户组件', () => {
it('获取用户数据', async () => {
// 类型安全的模拟实现
vi.mocked(fetchUser).mockResolvedValue({ id: 1, name: '测试' });
// ... 测试代码
expect(fetchUser).toHaveBeenCalledWith(1);
});
});
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
describe('日期处理', () => {
beforeEach(() => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2026-01-01'));
});
afterEach(() => {
vi.useRealTimers();
});
it('使用模拟日期', () => {
expect(new Date().getFullYear()).toBe(2026);
});
});
import { vi, describe, it, expect } from 'vitest';
describe('环境', () => {
it('全局模拟 fetch', async () => {
const mockFetch = vi.fn().mockResolvedValue({
ok: true,
json: () => Promise.resolve({ data: '测试' }),
});
vi.stubGlobal('fetch', mockFetch);
const response = await fetch('/api/test');
expect(mockFetch).toHaveBeenCalledWith('/api/test');
vi.unstubAllGlobals();
});
});
import { describe, it, expect } from 'vitest';
describe('组件输出', () => {
it('匹配快照', () => {
const result = renderComponent({ title: '你好' });
expect(result).toMatchSnapshot();
});
it('匹配内联快照', () => {
const result = { name: '测试', count: 42 };
expect(result).toMatchInlineSnapshot(`
{
"count": 42,
"name": "测试",
}
`);
});
});
# 更新所有快照
vitest run --update
# 交互式更新
vitest --ui
直接在源文件中编写测试代码(生产环境会被 tree-shaken):
// src/utils/math.ts
export function add(a: number, b: number): number {
return a + b;
}
// 源码内测试块
if (import.meta.vitest) {
const { describe, it, expect } = import.meta.vitest;
describe('add', () => {
it('两数相加', () => {
expect(add(1, 2)).toBe(3);
});
});
}
源码内测试配置:
// vitest.config.ts
export default defineConfig({
test: {
includeSource: ['src/**/*.{js,ts}'],
},
define: {
'import.meta.vitest': 'undefined', // 生产环境 tree-shake
},
});
// vitest.workspace.ts
import { defineWorkspace } from 'vitest/config';
export default defineWorkspace([
// 每个包可以有自己的配置
'packages/*/vitest.config.ts',
// 或内联定义
{
test: {
name: '单元测试',
include: ['src/**/*.test.ts'],
environment: 'node',
},
},
{
test: {
name: '浏览器测试',
include: ['src/**/*.browser.test.ts'],
browser: {
enabled: true,
provider: 'playwright',
name: 'chromium',
},
},
},
]);
// vitest.config.ts
export default defineConfig({
test: {
browser: {
enabled: true,
provider: 'playwright', // 或 'webdriverio'
name: 'chromium',
headless: true,
},
},
});
# 安装浏览器提供程序
pnpm add -D @vitest/browser playwright
# 安装覆盖率提供程序
pnpm add -D @vitest/coverage-v8
# 运行覆盖率测试
vitest run --coverage
// vitest.config.ts
export default defineConfig({
test: {
coverage: {
provider: 'v8',
reporter: ['text', 'html', 'lcov'],
exclude: [
'node_modules/',
'src/test/',
'**/*.d.ts',
],
thresholds: {
statements: 80,
branches: 80,
functions: 80,
lines: 80,
},
},
},
});
| Jest | Vitest |
|---|---|
jest.fn() | vi.fn() |
jest.mock() | vi.mock() |
jest.spyOn() | vi.spyOn() |
jest.useFakeTimers() | vi.useFakeTimers() |
jest.clearAllMocks() | vi.clearAllMocks() |
@jest/globals | vitest |
// 之前 (Jest)
import { jest } from '@jest/globals';
// 之后 (Vitest)
import { vi } from 'vitest';
2. 更新配置:
// jest.config.js → vitest.config.ts
export default defineConfig({
test: {
globals: true, // 启用 describe/it/expect 无需导入
environment: 'jsdom',
},
});
3. 将 jest. 替换为 vi.:
# 快速替换(仔细检查更改)
find src -name "*.test.ts" -exec sed -i 's/jest\./vi./g' {} \;
import { describe, it, expect } from 'vitest';
describe('异步操作', () => {
it('解析 Promise', async () => {
const result = await fetchData();
expect(result).toBeDefined();
});
it('拒绝并抛出错误', async () => {
await expect(failingOperation()).rejects.toThrow('预期错误');
});
});
import { describe, it, expect, beforeEach } from 'vitest';
describe('使用夹具', () => {
let testData: TestData;
beforeEach(() => {
testData = createTestFixture();
});
it('使用夹具', () => {
expect(testData.id).toBeDefined();
});
});
import { describe, it, expect } from 'vitest';
describe.each([
{ input: 1, expected: 2 },
{ input: 2, expected: 4 },
{ input: 3, expected: 6 },
])('double($input)', ({ input, expected }) => {
it(`返回 ${expected}`, () => {
expect(double(input)).toBe(expected);
});
});
vitest run -t "测试名称"
vitest run src/specific.test.ts
# 使用 Node 检查器
node --inspect-brk ./node_modules/vitest/vitest.mjs run
# 或使用 Vitest UI
vitest --ui
vitest # 监视模式(默认)
vitest run # 单次运行
vitest watch # 显式监视
// 确保模拟路径与导入路径完全匹配
vi.mock('./api'); // 匹配:import { x } from './api'
vi.mock('../api'); // 不同!对 './api' 导入无效
// vitest.config.ts - 用于 CJS 依赖
export default defineConfig({
test: {
deps: {
inline: ['有问题的-cjs-包'],
},
},
});
// 如果使用 globals: true 但 TypeScript 报错
// 添加到 tsconfig.json:
{
"compilerOptions": {
"types": ["vitest/globals"]
}
}
testing-patterns 技能 - 通用测试模式testing-library 技能 - React Testing Library 集成每周安装数
145
代码仓库
GitHub 星标数
652
首次出现
2026年2月6日
安全审计
安装于
claude-code117
opencode101
gemini-cli94
replit93
codex89
cursor82
Status : Production Ready Last Updated : 2026-02-06 Vitest Version : 4.x Vite Compatibility : 6.x
# Install
pnpm add -D vitest
# Add to package.json
{
"scripts": {
"test": "vitest",
"test:run": "vitest run",
"test:coverage": "vitest run --coverage"
}
}
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
environment: 'node',
},
});
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['./src/test/setup.ts'],
css: true,
},
});
import { defineConfig } from 'vitest/config';
import { cloudflare } from '@cloudflare/vite-plugin';
export default defineConfig({
plugins: [cloudflare()],
test: {
globals: true,
environment: 'node',
// Workers tests often need longer timeouts for D1/KV
testTimeout: 10000,
},
});
import { vi, describe, it, expect } from 'vitest';
import { fetchUser } from './api';
// Mock entire module
vi.mock('./api', () => ({
fetchUser: vi.fn(),
}));
describe('User component', () => {
it('fetches user data', async () => {
// Type-safe mock implementation
vi.mocked(fetchUser).mockResolvedValue({ id: 1, name: 'Test' });
// ... test code
expect(fetchUser).toHaveBeenCalledWith(1);
});
});
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
describe('Date handling', () => {
beforeEach(() => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2026-01-01'));
});
afterEach(() => {
vi.useRealTimers();
});
it('uses mocked date', () => {
expect(new Date().getFullYear()).toBe(2026);
});
});
import { vi, describe, it, expect } from 'vitest';
describe('Environment', () => {
it('mocks fetch globally', async () => {
const mockFetch = vi.fn().mockResolvedValue({
ok: true,
json: () => Promise.resolve({ data: 'test' }),
});
vi.stubGlobal('fetch', mockFetch);
const response = await fetch('/api/test');
expect(mockFetch).toHaveBeenCalledWith('/api/test');
vi.unstubAllGlobals();
});
});
import { describe, it, expect } from 'vitest';
describe('Component output', () => {
it('matches snapshot', () => {
const result = renderComponent({ title: 'Hello' });
expect(result).toMatchSnapshot();
});
it('matches inline snapshot', () => {
const result = { name: 'test', count: 42 };
expect(result).toMatchInlineSnapshot(`
{
"count": 42,
"name": "test",
}
`);
});
});
# Update all snapshots
vitest run --update
# Interactive update
vitest --ui
Test code directly in source files (tree-shaken in production):
// src/utils/math.ts
export function add(a: number, b: number): number {
return a + b;
}
// In-source test block
if (import.meta.vitest) {
const { describe, it, expect } = import.meta.vitest;
describe('add', () => {
it('adds two numbers', () => {
expect(add(1, 2)).toBe(3);
});
});
}
Config for in-source testing:
// vitest.config.ts
export default defineConfig({
test: {
includeSource: ['src/**/*.{js,ts}'],
},
define: {
'import.meta.vitest': 'undefined', // Tree-shake in production
},
});
// vitest.workspace.ts
import { defineWorkspace } from 'vitest/config';
export default defineWorkspace([
// Each package can have its own config
'packages/*/vitest.config.ts',
// Or define inline
{
test: {
name: 'unit',
include: ['src/**/*.test.ts'],
environment: 'node',
},
},
{
test: {
name: 'browser',
include: ['src/**/*.browser.test.ts'],
browser: {
enabled: true,
provider: 'playwright',
name: 'chromium',
},
},
},
]);
// vitest.config.ts
export default defineConfig({
test: {
browser: {
enabled: true,
provider: 'playwright', // or 'webdriverio'
name: 'chromium',
headless: true,
},
},
});
# Install browser provider
pnpm add -D @vitest/browser playwright
# Install coverage provider
pnpm add -D @vitest/coverage-v8
# Run with coverage
vitest run --coverage
// vitest.config.ts
export default defineConfig({
test: {
coverage: {
provider: 'v8',
reporter: ['text', 'html', 'lcov'],
exclude: [
'node_modules/',
'src/test/',
'**/*.d.ts',
],
thresholds: {
statements: 80,
branches: 80,
functions: 80,
lines: 80,
},
},
},
});
| Jest | Vitest |
|---|---|
jest.fn() | vi.fn() |
jest.mock() | vi.mock() |
jest.spyOn() | vi.spyOn() |
jest.useFakeTimers() | vi.useFakeTimers() |
// Before (Jest)
import { jest } from '@jest/globals';
// After (Vitest)
import { vi } from 'vitest';
2. Update config:
// jest.config.js → vitest.config.ts
export default defineConfig({
test: {
globals: true, // Enables describe/it/expect without imports
environment: 'jsdom',
},
});
3. Replace jest. with vi.:
# Quick replace (review changes carefully)
find src -name "*.test.ts" -exec sed -i 's/jest\./vi./g' {} \;
import { describe, it, expect } from 'vitest';
describe('async operations', () => {
it('resolves promise', async () => {
const result = await fetchData();
expect(result).toBeDefined();
});
it('rejects with error', async () => {
await expect(failingOperation()).rejects.toThrow('Expected error');
});
});
import { describe, it, expect, beforeEach } from 'vitest';
describe('with fixtures', () => {
let testData: TestData;
beforeEach(() => {
testData = createTestFixture();
});
it('uses fixture', () => {
expect(testData.id).toBeDefined();
});
});
import { describe, it, expect } from 'vitest';
describe.each([
{ input: 1, expected: 2 },
{ input: 2, expected: 4 },
{ input: 3, expected: 6 },
])('double($input)', ({ input, expected }) => {
it(`returns ${expected}`, () => {
expect(double(input)).toBe(expected);
});
});
vitest run -t "test name"
vitest run src/specific.test.ts
# With Node inspector
node --inspect-brk ./node_modules/vitest/vitest.mjs run
# Or use Vitest UI
vitest --ui
vitest # Watch mode (default)
vitest run # Single run
vitest watch # Explicit watch
// Ensure mock path matches import path exactly
vi.mock('./api'); // Matches: import { x } from './api'
vi.mock('../api'); // Different! Won't work for './api' imports
// vitest.config.ts - for CJS dependencies
export default defineConfig({
test: {
deps: {
inline: ['problematic-cjs-package'],
},
},
});
// If using globals: true but TypeScript complains
// Add to tsconfig.json:
{
"compilerOptions": {
"types": ["vitest/globals"]
}
}
testing-patterns skill - General testing patternstesting-library skill - React Testing Library integrationWeekly Installs
145
Repository
GitHub Stars
652
First Seen
Feb 6, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code117
opencode101
gemini-cli94
replit93
codex89
cursor82
Skills CLI 使用指南:AI Agent 技能包管理器安装与管理教程
40,000 周安装
jest.clearAllMocks() | vi.clearAllMocks() |
@jest/globals | vitest |