为什么要选择 Vitest?

在 Vitest 之前,前端普遍的测试框架是 Jest。Jest 是由 Facebook 开源的一款测试框架,它本身集成了断言库、mock、快照测试、覆盖率报告等功能。

Vitest 是一个基于 Vite 的测试框架,它可以做到与 Vite 通用配置。也就是说,如果你在 Vite 中使用插件支持了JSX语法,做单元测试的时候就无需再配置一遍了,这点非常重要。并且 Vite 兼容了大部分 Jest 的使用方法,这样以往 Jest 的使用经验依然可以用在 Vitest 中使用,没有太多的重复学习过程。另外 Vitest 更加注重性能,尽可能多地使用 Worker 线程并发执行,可以提高测试的运行效率。

总结一下 Vitest 的优点:

  • Vite 同配置;
  • 大量兼容 JestAPI;
  • 高执行效率。

    官网地址

    Vitest

    vscode配套插件

    Vitest - Visual Studio Marketplace

    配置测试环境

    配置 Vitest 测试组件库需要以下三个库:

  • vitest :测试框架,用于执行整个测试过程并提供断言库、mock、覆盖率;

  • happy-dom:是用于提供在 Node 环境中的 Dom 仿真模型;
  • @vue/test-utils 工具库: Vue推荐的测试工具库。

A Crash Course | Vue Test Utils

@vue/test-utils 工具库是为了简化vue的测试过程而设计的。实际上使用 jest 或者 vitest 也可以直接对 vue 的进行测试。但是如果每次都需要编写初始化vue实例、渲染组件等操作,并且对Dom 断言也比较繁琐。比较好的办法是将这些针对 vue 测试的过程进程封装。当然这些封装是针对虽有vue项目通用的。这也就是 @vue/test-utils 的来历

  1. "devDependencies": {
  2. "@iconify-json/ic": "^1.1.9",
  3. "@types/node": "^18.11.9",
  4. "@vitejs/plugin-vue": "^3.2.0",
  5. "@vitejs/plugin-vue-jsx": "^2.1.0",
  6. "@vue/test-utils": "^2.2.1",
  7. "happy-dom": "^7.6.6",
  8. "unocss": "^0.46.3",
  9. "vite": "^3.2.2",
  10. "vitest": "^0.24.5"
  11. }

配置vite.config

  1. import { defineConfig } from 'vite'
  2. export default defineConfig({
  3. // ...
  4. test: {
  5. // enable jest-like global test APIs
  6. globals: true,
  7. // simulate DOM with happy-dom
  8. // (requires installing happy-dom as a peer dependency)
  9. environment: 'happy-dom',
  10. // 支持tsx组件,很关键
  11. transformMode: {
  12. web: [/.[tj]sx$/]
  13. }
  14. }
  15. })

由于 test 属性属于 Vitest 的扩展属性,vite 原生配置中并没有定义这个属性。 解决的办法就是在 vite.config.ts 中增加一个类型定义声明
image.png

  • describe:这个函数接受一个名字和一个函数,用于将相关的测试组合在一起。当你为一个有多个测试点(如逻辑和外观)的组件编写测试时,它就会很方便。
  • test/it:这个函数代表被测试的实际代码块。它接受一个字符串,通常是测试案例的名称或描述(例如,渲染成功的正确样式)和另一个函数,所有的检查和测试在这里进行。
  • expect: 这个函数用于测试值或创建断言。它接受一个预期为实际值(字符串、数字、对象等)的参数x,并使用任何支持的方法对其进行评估(例如toEqual(y),检查 x 是否与 y 相同)。

编辑测试文件

默认可以匹配的文件为 [filename].{spec, test}.{ts, js} :::success 在package.json中新增快捷命令: “test”: “vitest” :::

  1. import { shallowMount } from "@vue/test-utils";
  2. import { describe, expect, test } from "vitest";
  3. import Button from "@/button/index";
  4. // 测试分组
  5. describe("Button", () => {
  6. // mount
  7. test("mount @vue/test-utils", () => {
  8. // @vue/test-utils
  9. const wrapper = shallowMount(Button, {
  10. slots: {
  11. default: "Button",
  12. },
  13. });
  14. // 断言
  15. expect(wrapper.text()).toBe("Button");
  16. });
  17. });

image.png