Vitest 学习与实践总结:在 React + TypeScript 项目中快速上手单元测试

Vitest 学习与实践总结:在 React + TypeScript 项目中快速上手单元测试

今天我用4个小时学习和实践了 Vitest 这个前端测试工具。主要是了解一下它是什么,怎么用,尤其是怎么在我们常用的 React + TypeScript 项目里用。下面是我学习的一个简单总结和记录。

一、Vitest 是个啥?

简单来说,Vitest 就是一个用来给代码做测试的工具,比如测试一个函数能不能正常工作,或者一个 React 组件显示得对不对。

它最大的特点是,而且和 Vite 项目(我们现在用的项目构建工具)搭配起来特别方便,几乎不需要做太多额外的配置。

二、为啥要用它?(它的好处)
  1. 速度快:因为它用到了 Vite 的一些特性,每次跑测试的时候几乎不需要重新打包,所以感觉测试跑起来飞快,节省时间。
  2. 开箱即用:对于我们这种用 Vite 创建的 React+TS 项目,不用折腾太多配置就能直接用,很方便。
  3. 和 Jest 差不多:它的写法和用法和另一个流行的测试工具 Jest 很像,所以如果以前写过 Jest,学起来就非常容易。
三、在 React + TypeScript 项目里怎么用?

我跟着教程和文档,大概走了下面几个步骤:

1. 安装东西

首先在项目里安装了 Vitest 和另外一个用来测试 React 组件的库(叫 @testing-library/react),安装命令大概是这样的:

dart 复制代码
npm install -D vitest @testing-library/react @testing-library/jest-dom jsdom

2. 创建配置文件

在项目根目录创建了一个 vitest.config.ts 文件,进行一些简单配置,告诉 Vitest 要用哪个环境(比如 jsdom 来模拟浏览器环境)。

javascript 复制代码
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  test: {
    environment: 'jsdom',
  },
});

3. 写一个简单的测试例子

我学着给一个最简单的组件写测试。比如,我们有一个按钮组件 Button.tsx

  • 组件代码(Button.tsx)

    typescript 复制代码
    interface ButtonProps {
      text: string;
      onClick: () => void;
    }
    export const Button = ({ text, onClick }: ButtonProps) => {
      return <button onClick={onClick}>{text}</button>;
    };
  • 测试代码(Button.test.ts)

在旁边创建一个测试文件,用来检查这个组件能不能正常显示文字,以及点击能不能生效。

javascript 复制代码
import { describe, it, expect, vi } from 'vitest'; // 从vitest引入工具
import { render, screen, fireEvent } from '@testing-library/react'; // 引入React测试库
import { Button } from './Button'; // 引入要测试的组件

describe('Button 组件', () => {
  it('应该在页面上正确显示文字', () => {
    // 1. 渲染组件
    render(<Button text="点击我" onClick={() => {}} />);
    // 2. 在屏幕上找到包含"点击我"文字的元素
    const buttonElement = screen.getByText('点击我');
    // 3. 断言(期望)这个元素确实在文档里
    expect(buttonElement).toBeInTheDocument();
  });

  it('点击按钮时应该调用传入的函数', () => {
    // 1. 创建一个模拟函数,用来检查它有没有被调用
    const mockClick = vi.fn();
    // 2. 渲染组件
    render(<Button text="点击我" onClick={mockClick} />);
    // 3. 找到按钮
    const buttonElement = screen.getByText('点击我');
    // 4. 模拟一次点击事件
    fireEvent.click(buttonElement);
    // 5. 断言(期望)我们传入的模拟函数被调用了一次
    expect(mockClick).toHaveBeenCalledTimes(1);
  });
});

4. 运行测试

最后在 package.json 里加一个命令,然后运行它就能看到测试结果了。

json 复制代码
// package.json
"scripts": {
  "test": "vitest"
}

在终端里跑命令:

arduino 复制代码
npm run test

如果测试通过了,终端里就会显示绿色的对勾,告诉你所有测试都成功了,看着很有成就感。

四、对于组件来说,应该测试哪些方面?

像用户一样思考

测试类型 关键问题
✅ 渲染测试 用户看到了什么?
✅ 交互测试 用户操作后发生了什么?
✅ Props 测试 不同输入下行为是否正确?
✅ 条件渲染 内容是否在正确时机显示/隐藏?
✅ 异步测试 数据加载后 UI 是否更新?
  • @testing-library/react:用于渲染和查询

  • @testing-library/jest-dom:提供 toBeInTheDocument() 等断言

  • vi.fn() / vi.spyOn():模拟函数

  • waitFor / findBy:处理异步

  • userEvent(比 fireEvent 更真实)

具体场景

场景 推荐测试方式
按钮、输入框、卡片等 UI 组件 测试渲染 + 交互
表单组件 测试输入、验证、提交
模态框、下拉菜单 测试显示/隐藏、点击遮罩关闭
列表组件 测试数据渲染、空状态、加载状态
容器组件(带逻辑) 模拟 API,测试数据流
自定义 Hook 单独测试 Hook 行为(用 renderHook
四、总结

通过今天的学习,我感觉 Vitest 确实很简单易用,配置起来不麻烦,写测试的语法也很清晰。对于我们现在的项目来说,是一个很不错的选择。

相关推荐
红尘伴蝶舞2 天前
Android 17 局域网调试与 ACCESS_LOCAL_NETWORK 权限隔离实践
kotlin·测试·设计
栈溢出的浪漫3 天前
Python单元测试框架覆盖率-Coverage
python·单元测试·工具·覆盖率·coverage
名字还没想好☜4 天前
Go 表驱动测试实战:用 t.Run 子测试组织可维护的单元测试
golang·单元测试·log4j·go·testing
Dr.kangder4 天前
嵌入式软件单元测试:从理论到实践
架构·单元测试·嵌入式·测试覆盖率
Apifox6 天前
Apifox 7 月更新|审计日志、密钥扫描防护、Postman/OpenAPI / Swagger 导入体验优化
前端·后端·测试
狂师6 天前
AI 测试提效 | 告别手工写脚本,分享我的 Playwright + Skill 批量生成 UI 自动化脚本方案
人工智能·测试·全栈
Python私教7 天前
Codex 写出的代码能跑却算错钱:我用 3 个测试拆穿一次 AI 编程幻觉
python·单元测试·ai编程
ClouGence7 天前
一个人录好的测试用例,团队怎么一起用?
前端·测试
狂师7 天前
AI 测试提效 | 告别手动抓取元素,分享我的 ui-page-parser + Skill UI 自动化提效方案
人工智能·agent·测试