常用的测试方案大致分为有 4 种:
- 端对端测试:利用一个很像用户行为的机器人来和 App 交互,并验证功能是否正常。有时也会说 “功能测试” 或 E2E。
- 集成测试:验证多个单元是否能协调共同工作。
- 单元测试:验证单独隔离的部分是否正常工作。
- 静态测试:捕获写代码时的错别字和类型错误
Vitest 与 Jest 兼容,具有开箱即用的 ESM、Typescript 和 JSX 支持,并且由 esbuild 提供支持。它在测试过程中使用 Vite 开发服务器来转换你的文件,并监听你的应用程序的相同配置(通过vite.config.js),从而消除了使用Jest等测试替代品所涉及的重复工作。
为什么要进行单元测试?
- 验证功能:单元测试确保代码做正确的事情并且不做任何不应该做的事情——大多数错误发生在这里。
- 防止代码回归:当我们发现错误时,添加单元测试来检查场景可以防止代码更改在将来重新引入错误。
- 记录代码:通过正确的单元测试,一套完整的测试和结果提供了应用程序应该如何工作的规范。
- 保护您的应用程序:单元测试可以检查可利用的漏洞(例如启用恶意 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.alias 和 plugins 的配置将会在 Vitest 中开箱即用。如果你想在测试期间想要不同的配置,你可以:
- 创建
vitest.config.ts
,优先级将会最高。 - 将
--config
选项传递给 CLI,例如vitest --config ./path/to/vitest.config.ts
。 - 在
defineConfig
上使用process.env.VITEST
或mode
属性(如果没有被覆盖,将设置为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
应该测试什么?
思考这个组件需要做什么,以达到预期的功能。
测试依赖项
有时我们需要个根元素, 类似‘#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"
},
失败给出对应的提示
通过的提示
查看覆盖率
最后我们可以执行pnpm run coverage or pnpm -w run coverage来查看我们测试的覆盖情况
%stmts是语句覆盖率(statement coverage):是不是每个语句都执行了?
%Branch分支覆盖率(branch coverage):是不是每个if代码块都执行了?
%Funcs函数覆盖率(function coverage):是不是每个函数都调用了?
%Lines行覆盖率(line coverage):是不是每一行都执行了?
总结
再写单测的时候思考 组件 或 方法的正确性