青训营笔记 | 如何使用Vitest

237 阅读6分钟

一、Vitest 简介

Vitest 是一个由 Vite 提供支持的极速单元测试框架,专门用于 JavaScript 和 TypeScript 项目。它利用了 Vite 的快速模块解析和热模块替换功能,能够提供极快的测试运行速度,同时还具备简洁的 API 和丰富的功能,使得编写和运行单元测试变得高效且便捷。

二、安装 Vitest

在项目中安装 Vitest,可以使用以下命令:

pnpm install --save-dev vitest

三、配置 Vitest

  1. 创建配置文件
    • 在项目根目录下创建 vitest.config.js 文件。
    • 一个基本的配置示例如下:
import { defineConfig } from 'vite';
export default defineConfig({
  test: {
    include: ['**/__tests__/**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', '**/*.{spec,test}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
    // 排除的文件或目录
    exclude: [],
    // 环境设置,例如可以设置为 'jsdom' 用于浏览器环境模拟
    environment: 'jsdom',
    // 测试覆盖率相关配置
    coverage: {
      reporter: ['text', 'json', 'html']
    }
  }
});
  1. 在 package.json 中添加脚本
    • 在 package.json 文件的 scripts 部分添加测试脚本,例如:
{
  "scripts": {
    "test": "vitest"
  }
}

四、编写测试用例

  1. 创建测试文件

    • 按照配置文件中的匹配模式创建测试文件。例如,对于一个名为 math.js 的源文件,在 __tests__ 目录下创建 math.spec.js 文件。
  2. 编写测试代码

    • 以测试一个简单的加法函数为例:
// math.js
export function add(a, b) {
  return a + b;
}

// math.spec.js
import { add } from '../math';

describe('add function', () => {
  it('should add two numbers correctly', () => {
    const result = add(2, 3);
    expect(result).toBe(5);
  });
});
  • 在测试文件中,使用 describe 来组织一组相关的测试,it 定义单个测试用例。expect 是用于断言的函数,这里断言 add 函数的结果是否符合预期。

五、运行测试

在项目根目录下执行 npm run test 或者 yarn test,Vitest 就会根据配置查找并运行测试用例。它会在控制台输出测试结果,包括通过的测试数量、失败的测试数量以及每个测试用例的详细信息。如果配置了测试覆盖率,还会生成覆盖率报告,显示代码被测试的比例以及未覆盖的部分,有助于评估测试的完整性和有效性。

六、组件测试

(一)组件测试概述

在现代的 JavaScript 和 TypeScript 项目中,尤其是使用像 React、Vue 等框架开发的项目里,组件测试是非常重要的一环。组件是构建用户界面的基本单元,对组件进行有效的测试可以确保其功能的正确性、交互的合理性以及在不同场景下的稳定性等。Vitest 同样可以很好地支持组件测试,下面以 React 组件为例来详细介绍组件测试的相关内容。

(二)准备测试环境

  1. 安装相关依赖
    如果是测试 React 组件,首先需要安装 React 相关的测试库,比如 @testing-library/react,它提供了方便的工具来查询和操作 React 组件在测试环境下的 DOM 元素等。可以使用以下命令安装:
pnpm install --save-dev @testing-library/react

同时,根据项目具体情况,可能还需要安装其他辅助测试的库,比如 jest-dom(虽然我们这里用的是 Vitest,但有些它提供的用于断言 DOM 相关情况的工具也很实用),安装命令如下:

pnpm install --save-dev jest-dom
  1. 配置 Vitest 支持 React 组件测试
    在 vitest.config.js 文件中,需要对测试环境等进行适当配置以适配 React 组件测试。例如:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  test: {
    include: ['**/__tests__/**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', '**/*.{spec,test}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
    exclude: [],
    environment: 'jsdom',
    globals: true, // 开启全局变量支持,方便在测试文件中直接使用 React 等相关变量
    setupFiles: ['./src/setupTests.js'], // 可以指定一个设置文件,用于初始化一些测试环境相关的配置等
    coverage: {
      reporter: ['text', 'json', 'html']
    }
  }
});

这里通过 @vitejs/plugin-react 插件来让 Vite(进而 Vitest)能够正确处理 React 相关的语法等,同时配置了一些测试相关的基础设置,比如开启全局变量方便使用 React,以及指定一个设置文件(假设 src/setupTests.js 这个文件后续可以用于导入一些常用的测试辅助函数等)。

(三)编写组件测试用例

假设我们有一个简单的 React 计数器组件 Counter.jsx,代码如下:

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>当前计数: {count}</p>
      <button onClick={() => setCount(count + 1)}>增加计数</button>
    </div>
  );
};

export default Counter;

我们在 __tests__ 目录下创建 Counter.spec.jsx 文件来对其进行测试,代码如下:

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Counter from '../Counter';

describe('Counter 组件测试', () => {
  it('初始计数应该显示为 0', () => {
    render(<Counter />);
    const countElement = screen.getByText('当前计数: 0');
    expect(countElement).toBeInTheDocument();
  });

  it('点击增加计数按钮后,计数应该增加', () => {
    render(<Counter />);
    const button = screen.getByRole('button', { name: '增加计数' });
    userEvent.click(button);
    const updatedCountElement = screen.getByText('当前计数: 1');
    expect(updatedCountElement).toBeInTheDocument();
  });

  it('多次点击增加计数按钮后,计数应该正确累加', () => {
    render(<Counter />);
    const button = screen.getByRole('button', { name: '增加计数' });
    userEvent.click(button);
    userEvent.click(button);
    userEvent.click(button);
    const finalCountElement = screen.getByText('当前计数: 3');
    expect(finalCountElement).toBeInTheDocument();
  });
});
  • 在第一个测试用例中,通过 render 函数将 Counter 组件渲染到测试环境的虚拟 DOM 中,然后使用 screen.getByText 去查找页面中显示当前计数为 0 的元素,并使用 expect 断言这个元素确实存在于文档中,以此验证组件初始渲染时计数显示是否正确。

  • 第二个测试用例,同样先渲染组件,然后找到 “增加计数” 按钮,通过 userEvent.click 模拟用户点击按钮的操作,之后再去查找显示计数为 1 的元素,断言其存在,验证点击按钮后计数是否能正确增加。

  • 第三个测试用例则是多次模拟点击按钮的操作,最后验证计数是否按照预期累加到了 3,更全面地测试了组件计数累加的功能。

通过这样一系列的测试用例,可以较为全面地对 React 组件的功能进行验证,确保其在各种交互场景下都能按照预期工作。当然,对于更复杂的组件,还可以测试诸如组件的样式是否正确应用(结合相关的样式测试库)、组件在不同 props 传入情况下的表现等多方面的内容。

总之,利用 Vitest 进行组件测试可以结合各种前端测试库,构建出完善的测试体系,保障项目中组件的质量,进而提升整个项目的稳定性和可靠性。