单元测试之 Vitest 进行组件测试

常用的测试方案大致分为有 4 种:

  • 端对端测试:利用一个很像用户行为的机器人来和 App 交互,并验证功能是否正常。有时也会说 “功能测试” 或 E2E。
  • 集成测试:验证多个单元是否能协调共同工作。
  • 单元测试:验证单独隔离的部分是否正常工作。
  • 静态测试:捕获写代码时的错别字和类型错误

Vitest 与 Jest 兼容,具有开箱即用的 ESM、Typescript 和 JSX 支持,并且由 esbuild 提供支持。它在测试过程中使用 Vite 开发服务器来转换你的文件,并监听你的应用程序的相同配置(通过vite.config.js),从而消除了使用Jest等测试替代品所涉及的重复工作。

官网

image.png

为什么要进行单元测试?

  • 验证功能:单元测试确保代码做正确的事情并且不做任何不应该做的事情——大多数错误发生在这里。
  • 防止代码回归:当我们发现错误时,添加单元测试来检查场景可以防止代码更改在将来重新引入错误。
  • 记录代码:通过正确的单元测试,一套完整的测试和结果提供了应用程序应该如何工作的规范。
  • 保护您的应用程序:单元测试可以检查可利用的漏洞(例如启用恶意 SQL 注入的漏洞)。

如何使用 Vitest 来测试组件

pnpm add -D vitest

or
npm install -D vitest
or
yarn add -D vitest

配置 Vitest

Vitest 的主要优势之一是它与 Vite 的统一配置。如果存在,vitest 将读取你的根目录 vite.config.ts 以匹配插件并设置为你的 Vite 应用程序。例如,你的 Vite 有 resolve.aliasplugins 的配置将会在 Vitest 中开箱即用。如果你想在测试期间想要不同的配置,你可以:

  • 创建 vitest.config.ts,优先级将会最高。
  • --config 选项传递给 CLI,例如 vitest --config ./path/to/vitest.config.ts
  • defineConfig 上使用 process.env.VITESTmode 属性(如果没有被覆盖,将设置为 test)有条件地在 vite.config.ts 中应用不同的配置。

如果你已经在使用 Vite,请在 Vite 配置中添加 test 属性。你还需要使用 三斜杠指令 在你的配置文件的顶部引用。

Vitest 提供 environment 选项以在特定环境中运行代码,可以使用 environmentOptions 选项修改环境的行为方式。默认情况下,可以使用这些环境:

  • node 为默认环境
  • jsdom 通过提供 Browser API 模拟浏览器环境,使用 jsdom
  • happy-dom 通过提供 Browser API 模拟浏览器环境,被认为比 jsdom 更快,但缺少一些 API,使用 happy-dom
// <reference types="vitest" />
import { defineConfig } from 'vite'

export default defineConfig({
  test: {
            environment: "happy-dom"
  },
})

事例演示 Button

image.png

应该测试什么?

思考这个组件需要做什么,以达到预期的功能。

测试依赖项

有时我们需要个根元素, 类似‘#app’一样的挂载点,我们需要访问Vue Test Utils的mount方法,这是Vue.js的官方测试工具库

常见的Vitest方法

describe:这个函数接受一个名字和一个函数,用于将相关的测试组合在一起。当你为一个有多个测试点(如逻辑和外观)的组件编写测试时,它就会很方便。

test/it:这个函数代表被测试的实际代码块。它接受一个字符串,通常是测试案例的名称或描述(例如,渲染成功的正确样式)和另一个函数,所有的检查和测试在这里进行。

expect: 这个函数用于测试值或创建断言。它接受一个预期为实际值(字符串、数字、对象等)的参数x,并使用任何支持的方法对其进行评估(例如toEqual(y),检查 x 是否与 y 相同)。

toContain:toContain 断言实际值是否在数组中。toContain 还可以检查一个字符串是否是另一个字符串的子串。自 Vitest 1.0 起,如果我们需要在类似浏览器的环境中运行测试,此断言还可以检查类是否包含在 classList 中,或一个元素是否包含在另一个元素中。

测试button 组件 button.test.ts

import { describe, expect, it } from "vitest";
import { mount } from '@vue/test-utils'
import button from '../button.vue'
// The component to test


describe('test Button', () => {
    it("should render slot", () => {
        const wrapper = mount(button, {
            slots: {
                default: 'Hello world'
            }
        })

        // Assert the rendered text of the component
        expect(wrapper.text()).toContain('Hello world')
    })
    it("should have class", () => {
        const wrapper = mount(button, {
            props: {
                type: 'primary'
            }
        })
        expect(wrapper.classes()).toContain('k-button--primary')
    })
})

运行测试

pnpm run test
由于Vitest的智能和即时观察模式,这个命令只需要运行一次,并在我们对测试文件进行更新和修改时被重新运行。

  "scripts": {
    "test": "pnpm run --filter ./packages/components test",
    "coverage": "pnpm run --filter ./packages/components coverage"
  },

失败给出对应的提示

image.png

通过的提示

image.png

查看覆盖率

最后我们可以执行pnpm run coverage or pnpm -w run coverage来查看我们测试的覆盖情况


image.png

%stmts是语句覆盖率(statement coverage):是不是每个语句都执行了?

%Branch分支覆盖率(branch coverage):是不是每个if代码块都执行了?

%Funcs函数覆盖率(function coverage):是不是每个函数都调用了?

%Lines行覆盖率(line coverage):是不是每一行都执行了?

总结

再写单测的时候思考 组件 或 方法的正确性

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容