所有分类
  • 所有分类
  • Html5资源
  • React资源
  • Vue资源
  • Php资源
  • ‌小程序资源
  • Python资源

Vitest 测试框架完全指南 – 极速单元测试解决方案

简介

Vitest 是一个由 Vite 驱动的单元测试框架,专为现代前端项目设计。它提供了极快的测试执行速度、原生 ESM 支持、TypeScript 开箱即用等特性。

主要特性

  • ⚡️ 极快的测试执行速度
  • 🔧 与 Vite 配置完全兼容
  • 📦 原生 ESM 支持
  • 🎯 TypeScript 开箱即用
  • 🖥️ 美观的 UI 界面
  • 🧪 丰富的测试 API

安装

使用 npm

npm install -D vitest

使用 yarn

yarn add -D vitest

使用 pnpm

pnpm add -D vitest

基本配置

package.json 配置

{
  "scripts": {
    "test": "vitest",
    "test:ui": "vitest --ui",
    "test:run": "vitest run",
    "coverage": "vitest run --coverage"
  }
}

vitest.config.ts 配置

import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    globals: true,
    environment: "jsdom",
    setupFiles: ["./src/test/setup.ts"],
  },
});

编写测试

基本测试结构

import { describe, it, expect } from "vitest";

describe("数学运算", () => {
  it("应该正确相加两个数字", () => {
    expect(1 + 2).toBe(3);
  });

  it("应该正确处理负数", () => {
    expect(-1 + 1).toBe(0);
  });
});

测试生命周期钩子

import {
  describe,
  it,
  beforeAll,
  afterAll,
  beforeEach,
  afterEach,
} from "vitest";

describe("用户管理", () => {
  beforeAll(() => {
    // 在所有测试前执行一次
    console.log("开始用户管理测试");
  });

  beforeEach(() => {
    // 在每个测试前执行
    // 设置测试数据
  });

  afterEach(() => {
    // 在每个测试后执行
    // 清理测试数据
  });

  afterAll(() => {
    // 在所有测试后执行一次
    console.log("用户管理测试完成");
  });

  it("应该创建新用户", () => {
    // 测试逻辑
  });
});

异步测试

import { describe, it, expect } from "vitest";

describe("异步操作", () => {
  it("应该处理 Promise", async () => {
    const result = await Promise.resolve("success");
    expect(result).toBe("success");
  });

  it("应该处理回调函数", (done) => {
    setTimeout(() => {
      expect(true).toBe(true);
      done();
    }, 100);
  });
});

测试运行器

命令行选项

# 运行所有测试
vitest

# 运行测试并监听文件变化
vitest --watch

# 运行特定测试文件
vitest src/components/Button.test.ts

# 运行匹配模式的测试
vitest --run -t "用户"

# 并行运行测试
vitest --threads

测试分组和过滤

describe.skip("跳过的测试组", () => {
  it("这个测试不会运行", () => {
    expect(true).toBe(false);
  });
});

describe.only("只运行这个组", () => {
  it("这个测试会运行", () => {
    expect(true).toBe(true);
  });
});

it.skip("跳过单个测试", () => {
  expect(true).toBe(false);
});

it.only("只运行这个测试", () => {
  expect(true).toBe(true);
});

模拟和存根

函数模拟

import { describe, it, expect, vi } from "vitest";

describe("函数模拟", () => {
  it("应该模拟函数调用", () => {
    const mockFn = vi.fn();
    mockFn("hello");

    expect(mockFn).toHaveBeenCalled();
    expect(mockFn).toHaveBeenCalledWith("hello");
    expect(mockFn).toHaveBeenCalledTimes(1);
  });

  it("应该模拟函数返回值", () => {
    const mockFn = vi.fn().mockReturnValue("mocked");
    expect(mockFn()).toBe("mocked");
  });
});

模块模拟

import { describe, it, expect, vi } from "vitest";

// 模拟整个模块
vi.mock("./utils", () => ({
  add: vi.fn().mockReturnValue(10),
  multiply: vi.fn().mockReturnValue(20),
}));

// 模拟部分模块
vi.mock("./api", async () => {
  const actual = await vi.importActual("./api");
  return {
    ...actual,
    fetchUser: vi.fn().mockResolvedValue({ id: 1, name: "Test" }),
  };
});

覆盖率

安装覆盖率工具

npm install -D @vitest/coverage-v8

配置覆盖率

// vitest.config.ts
export default defineConfig({
  test: {
    coverage: {
      provider: "v8",
      reporter: ["text", "json", "html"],
      exclude: ["node_modules/", "src/test/", "**/*.d.ts"],
    },
  },
});

运行覆盖率测试

# 生成覆盖率报告
vitest run --coverage

# 检查覆盖率阈值
vitest run --coverage --coverage.threshold.lines=80

UI 界面

安装 UI 界面

npm install -D @vitest/ui

启动 UI 界面

vitest --ui

UI 界面提供:

  • 实时测试结果
  • 测试覆盖率可视化
  • 测试执行时间分析
  • 交互式调试

配置选项

常用配置

import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    // 全局变量
    globals: true,

    // 测试环境
    environment: "jsdom",

    // 设置文件
    setupFiles: ["./src/test/setup.ts"],

    // 包含的文件
    include: ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],

    // 排除的文件
    exclude: ["node_modules", "dist", ".idea", ".git", ".cache"],

    // 超时时间
    testTimeout: 5000,

    // 钩子超时时间
    hookTimeout: 10000,

    // 并行运行
    threads: true,

    // 最大并发数
    maxConcurrency: 5,
  },
});

最佳实践

测试文件命名

  • 使用 .test.ts.spec.ts 后缀
  • 保持与源文件相同的目录结构

测试数据管理

// 使用工厂函数创建测试数据
const createUser = (overrides = {}) => ({
  id: 1,
  name: "Test User",
  email: "test@example.com",
  ...overrides,
});

it("应该显示用户信息", () => {
  const user = createUser({ name: "John" });
  // 测试逻辑
});

清理和重置

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

describe("API 测试", () => {
  beforeEach(() => {
    // 设置测试环境
  });

  afterEach(() => {
    // 清理模拟
    vi.clearAllMocks();
    vi.resetAllMocks();
  });
});

性能优化

  • 使用 vi.isolateModules() 隔离模块
  • 合理使用 beforeAllafterAll
  • 避免在测试中创建不必要的对象
原文链接:https://code.ifrontend.net/archives/1044,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?