ToB企服应用市场:ToB评测及商务社交产业平台

标题: 【前端】前端单元测试、覆盖率测试工具Vitest入门指南 [打印本页]

作者: 惊落一身雪    时间: 2024-7-31 13:02
标题: 【前端】前端单元测试、覆盖率测试工具Vitest入门指南
前言

单元测试的重要性不问可知,可以很大水平的减少一些bug的产生。在前端项目中,有很多用于单元测试的工具,如最常见的Jest。但对于由vite构建的前端项目而言,使用vite配套的vitest会更加方便、舒服。官方文档是最好的入门方式,这篇文章记录在入门过程中可能遇到的一些标题,方便想相识的人更快速的上手。本文暂时只介绍单元测试和覆盖率测试的使用方法。
安装与配置

安装方法


基础配置

在package.json文件中,添加以下代码:
  1. {
  2.   "scripts": {
  3.     "test": "vitest"
  4.   }
  5. }
复制代码
测试Vitest是否能正常工作

按照官方文档的示例,准备两个文件sum.ts和sum.test.ts(可以在项目根目录下创建一个test文件夹,专门用来存放测试文件):
  1. // sum.ts
  2. export function sum(a, b) {
  3.   return a + b
  4. }
复制代码
  1. // sum.test.ts
  2. import { expect, test } from 'vitest'
  3. import { sum } from './sum'
  4. test('adds 1 + 2 to equal 3', () => {
  5.   expect(sum(1, 2)).toBe(3)
  6. })
复制代码
然后,在终端中运行指令npm run test(大概yarn test)。
假如没故意外,那么将出现以下结果:

关键字解释

假如你之前没有用过Jest,那么对于sum.test.ts文件中的test、expect、toBe方法,肯定一头雾水。
  1. test(name: string, testFn: Function, timeout?: number | TestOptions): Promise<void>;
复制代码

  1. expect(actual).matcher(expected)
复制代码
此中,actual是一个表达式或变量,表现要查抄的实际值。matcher是一个函数,表现要使用的比较方法。expected是一个值或对象,表现期望的结果。
在本例中,expect(sum(1, 2)).toBe(3)表现使用expect方法来测试sum函数是否能正确地将两个数字相加。此处使用 toBe来举行断言,这是Vitest提供的一个匹配器函数,用于比较实际值和期望值是否严格相等。
配合IDE使用

Vitest在各大主流前端IDE中都有对应的插件供开发者更方便的使用测试功能,这里以vscode为例,直接在插件市场搜刮Vitest,点击安装即可。

然后打开sum.test.ts文件,可以看到test方法的那一行的左边出现了一个图标:

点击该图标即可运行该文件下的测试代码,右键该图标可以举行更多选择,比如调试。
实际应用

测试文件准备

所谓单元测试,指的是对最小测试单元举行测试。比如在项目中写了一个计算文本宽度的方法,方法写好之后假如直接拿过去用,除非是颠末验证的现有方法,否则是容易出现处理上的漏洞的。因此我们可以把这个方法单独提取出来,放到测试文件夹中。
  1. export function getTextWidth(str: string | number): number {
  2.         if (!str) return 0;
  3.         // 如果str是数字,则转换为字符串
  4.         if (typeof str === 'number') {
  5.                 str = str.toString();
  6.         }
  7.         if (str.length < 3) {
  8.                 return 40;
  9.         }
  10.         let regx = /^[0-9]+.?[0-9]*$/;
  11.         let flexWidth = 0;
  12.         for (const char of str) {
  13.                 if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
  14.                         // 如果是英文字符,为字符分配10个单位宽度
  15.                         flexWidth += 10;
  16.                 } else if (char >= '\u4e00' && char <= '\u9fa5') {
  17.                         // 如果是中文字符,为字符分配15个单位宽度
  18.                         flexWidth += 15;
  19.                 } else if (regx.test(char)) {
  20.                         flexWidth += 9;
  21.                 } else {
  22.                         // 其他种类字符,为字符分配7个单位宽度
  23.                         flexWidth += 7;
  24.                 }
  25.         }
  26.         return flexWidth;
  27. }
复制代码
  1. // textWidth.test.js
  2. import { expect, test, describe } from 'vitest'
  3. import { getTextWidth } from './utilTemp'
  4. describe('getTextWidth function', () => {
  5.   // test for empty string
  6.   test('returns 0 if the input is an empty string', () => {
  7.     expect(getTextWidth('')).toBe(0)
  8.   })
  9.   // test for single character
  10.   test('returns 40 if the input is a single character', () => {
  11.     expect(getTextWidth('a')).toBe(40)
  12.     expect(getTextWidth('中')).toBe(40)
  13.     expect(getTextWidth(1)).toBe(40)
  14.   })
  15.   // test for numbers
  16.   test('returns the correct width for numbers', () => {
  17.     expect(getTextWidth(123)).toBe(27)
  18.     expect(getTextWidth(3.14)).toBe(34)
  19.     expect(getTextWidth(-100)).toBe(34)
  20.   })
  21.   // test for english characters
  22.   test('returns the correct width for english characters', () => {
  23.     expect(getTextWidth('Hello')).toBe(50)
  24.     expect(getTextWidth('World')).toBe(50)
  25.     expect(getTextWidth('Hello World')).toBe(107)
  26.   })
  27.   // test for chinese characters
  28.   test('returns the correct width for chinese characters', () => {
  29.     expect(getTextWidth('你好')).toBe(40)
  30.     expect(getTextWidth('世界')).toBe(40)
  31.     expect(getTextWidth('你好世界')).toBe(60)
  32.   })
  33.   // test for mixed characters
  34.   test('returns the correct width for mixed characters', () => {
  35.     expect(getTextWidth('Hello你好')).toBe(80)
  36.     expect(getTextWidth('World世界')).toBe(80)
  37.     expect(getTextWidth('Hello World你好世界')).toBe(167)
  38.   })
  39. })
复制代码
然后在vscode里面点击运行,大概在下令行里实行yarn test(npm run test),就能看到结果了:

测试覆盖率

代码覆盖率是一种用于评估代码的质量和完整性的指标,它表现代码中有多少比例被测试用例所覆盖。测试覆盖率的工具可以资助开发者生成和检察覆盖率报告,从而发现代码中的潜伏标题和改进点。
  1. {
  2.   "scripts": {
  3.     "coverage": "vitest run --coverage"
  4.   }
  5. }
复制代码
  1. {
  2.         test: {
  3.                 reporters: ['default', 'html'],
  4.                 coverage: {
  5.                         enabled: true,
  6.                         provider: 'v8',
  7.                         cleanOnRerun: true,
  8.                         reporter: ['text', 'json', 'html'],
  9.                 },
  10.         },
  11. }
复制代码
  这里需要阐明的是,官方说在vite.config.ts的顶部添加三斜线指令/// <reference types="vitest" />即可在vite的配置文件里添加Vitest的选项,但我试了,会报类型错误,所以我直接把defineConfig的导入改为了import { defineConfig } from 'vitest/config';。大概你可以单独新建一个vitest.config.ts文件举行配置。
  配置完成后,运行yarn test,就能看到结果:

可以看到,utilTemp.ts这一行对应的列都为100,阐明覆盖率测试通过。(当然不肯定非得是百分百才算通过,但一样平常规定至少得90%)
通过UI检察结果

在下令行里检察测试结果相对来说不够直观,因此Vitest提供一个漂亮的 UI 界面来检察并与之交互。Vitest 的 UI 界面是可选的,你可以通过以下方式安装:
  1. yarn add -D @vitest/ui
复制代码
大概
  1. npm i -D @vitest/ui
复制代码
安装完后,实行指令:yarn test --ui,就会开启一个服务器,然后会在浏览器里自动打开Vitest UI的界面:

点击右侧的文件,可以详细检察测试代码的覆盖情况,绿色代表已覆盖,赤色代表未覆盖,阐明需要修改测试代码以包管全覆盖。

结语

至此,有关Vitest的入门操作已介绍完毕。当然,Vitest的功能远不止云云,更多的功能,比如组件测试、快照测试、以及更多的配置、API等,请自行转到官方文档相识。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4