• 第六章 搭建Vitest前端单元测试环境


    第六章 搭建Vitest前端单元测试环境

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

    总结一下 Vitest 的优点:

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

    开始搭建环境

    • 安装依赖
    pnpm i -D vitest@"0.25" happy-dom@"6.0.4" @vue/test-utils@"2.0.2"
    
    • 1

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

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

    • happy-dom: 是用于提供在 Node 环境中的 Dom 仿真模型

    • @vue/test-utils 工具库: Vue推荐的测试工具库, 官网文档

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

    • vite配置修改

    文件名:vite.config.ts

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

    enviroment属性中配置了 happy-dom,用于提供测试所需要的 Dom 仿真。测试是在 node 环境中运行的,而不是浏览器中,需要提供一个 Dom 对象的仿真。然后就是 transformMode,由于代码中使用的 TSX 语法,所以需要设置转换处理。

    在配置时,我们发现 ts文件会报错。这是由于 test 属性属于 Vitest 的扩展属性,vite 原生配置中并没有定义这个属性。

    在这里插入图片描述
    官方解决的办法就是在 vite.config.ts 中增加一个类型定义声明
    在这里插入图片描述

    • 修改vite配置文件,增加三斜线指令
    /// 
    import { defineConfig } from "vite";
    
    export default defineConfig({
      test: {
        // ...
      },
    });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    温馨提示:如果你的npm镜像是淘宝镜像错误不会消失!!!

    • 更改回原来的官方镜像
    npm config set registry https://registry.npmjs.org
    
    • 1
    • 删除pnpm.lock.json文件

    如果不删除,下载的地址还是原来的淘宝镜像

    • 删除node_modules整个文件夹

    删除所有以前的淘宝镜像

    • 重新安装所有依赖
    pnpm install
    
    • 1

    至此环境搭建完成。


    代码的小重构

    测试之前做一个代码的小重构。就是给每一个组件添加一个入口 index.ts

    将原来的 index.tsx =重命名=> Button.tsx , 新建一个 index.ts

    文件名:src/button/indxe.ts

    import Button from "./Button";
    
    // 导出Button组件
    export default Button ;
    
    • 1
    • 2
    • 3
    • 4

    编写测试用例

    文件名:src/button/__tests__/Button.test.ts

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

    在测试文件中创建一个 describe 分组。在第一个参数中输入【Button】,表明是针对 Button 的测试。编写测试用例 test ,使用 shallowMount 初始化组件,测试按钮是否工作正常,只需要断言判断按钮中的字符串是否正确就可以了。

    • 增加测试运行脚本

    文件名:package.json

      {
          "scripts": {
              "test": "vitest",
          }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 启动单元测试
    pnpm test
    
    • 1
    • 控制台查看结果
     DEV  v0.25.1 D:/MyWorkSpace/VUE3_WORKSPACE/StudyVueUI
    
     ✓ src/button/__tests__/Button.test.ts (1)
    
     Test Files  1 passed (1)
          Tests  1 passed (1)
       Start at  04:50:17
       Duration  1.58s (transform 812ms, setup 0ms, collect 363ms, tests 15ms)
    
    
     PASS  Waiting for file changes...
           press h to show help, press q to quit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    上面的测试只是测试了按钮的默认状态。对于按钮组件来讲,它的主要逻辑是根据不同的 props 属性来定制不同的样式。下面我们针对这些逻辑继续编写测试。

    在这里插入图片描述

    比如: color 属性是根据传入的不同条件定义不同的颜色,只需要让断言判断是否加载不同的属性就行了。

    • Color: default
    输入:color输出:css
    空(默认)bg-blue-500
    redbg-red-500
    • 增加测试用例

    文件名:src/button/__tests__/Button.test.ts

    describe('color', () => {
        test("default", () => {
          const wrapper = shallowMount(Button, {
            slots: {
              default: 'Button'
            }
          });
          expect(wrapper.classes().map(v => v.replace('\n','')).includes('bg-blue-500')).toBe(true)
        });
        test("red", () => {
          const wrapper = shallowMount(Button, {
            slots: {
              default: 'Button'
            },
            props: {
              color: 'red'
            }
          });
          expect(wrapper.classes().map(v => v.replace('\n','')).includes('bg-red-500')).toBe(true)
        });
      })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 启动测试命令
    pnpm test
    
    • 1
    • 控制台查看结果
     DEV  v0.25.1 D:/MyWorkSpace/VUE3_WORKSPACE/StudyVueUI
    
     ✓ src/button/__tests__/Button.test.ts (3)
    
     Test Files  1 passed (1)
          Tests  3 passed (3)
       Start at  04:57:30
       Duration  1.58s (transform 796ms, setup 0ms, collect 371ms, tests 18ms)
    
    
     PASS  Waiting for file changes...
           press h to show help, press q to quit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    编写测试的时候,使用 describe 创建一个子分组,用于测试 color 属性。然后设置不同的 color 属性值,用断言来判断是否输出对应的 css 样式。

    剩余的属性测试和 color 的测试非常类似,我们就不再赘述。在代码编写阶段,建议只对重点功能进行测试,没必要一定追求过高的测试覆盖率,因为前期过度地测试也会提高开发成本,拖慢开发进度。

    到目前为止,已经把组件库的测试框架搭好了。

  • 相关阅读:
    # 电脑必设优化项
    mysql视图中转换表字段的数据类型
    JAVA入门总结回顾
    javac不是内部命令
    JAVA集合(一)Collection接口
    DDR3 controller 之储存器介绍
    解读最早的草图-图像翻译工作SketchyGAN
    Android中的内存泄漏和内存溢出
    机器学习基础:奇异值分解(SVD)
    验证IP地址(字符串分割判断、正则表达式)
  • 原文地址:https://blog.csdn.net/qq_36362721/article/details/127827968