美文网首页
单元测试之 Vitest 进行组件测试

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

作者: 前端早晚自习 | 来源:发表于2023-12-13 16:25 被阅读0次

    常用的测试方案大致分为有 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):是不是每一行都执行了?

    总结

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

    相关文章

      网友评论

          本文标题:单元测试之 Vitest 进行组件测试

          本文链接:https://www.haomeiwen.com/subject/rowbgdtx.html