这是我参与「 第五届青训营 」伴学笔记创作活动的第 3 天
组件库:Vitest测试
一、测试基本常识
1、测试类型
-
单元测试
-
端到端测试(e2e)
-
组件测试
2、单元测试
-
jest
-
vitest(基于vite生态体系,更方便快捷)
二、Vitest测试环境搭建
1、安装vitest
npm i -D vitest happy-dom @testing-library/vue
2、配置vite.config.ts
/// <reference types="vitest" />
export default defineConfig({
test: {
// jest like test apis
globals: true,
// 模拟dom环境
environment: 'happy-dom',
// 支持tsx
transformMode: {
web: [/.[tj]sx$/]
}
}
})
3、配置tsconfig.json
"types": ["vitest/globals"]
-
加上之后支持vitest类型提示
4、测试文件的命名
-
xxx.test.ts
5、配置package.json
"test": "vitest",
6、启动测试命令
yarn test
三、写button的测试
1、原则
-
单元测试应该写的很小,仅覆盖单独函数、类、复用逻辑等
-
单元测试关注逻辑正确性,且仅关注程序功能的一小块
-
对于可视部分,组件验证基于输入的props、slots等渲染输出的结果
-
对于行为逻辑(点击),组件测试验证响应用户输入事件正确渲染更新和派发事件
2、button.ts源码
import { defineComponent, toRefs } from 'vue'
import { buttonProps, ButtonProps } from './button-types'
export default defineComponent({
name: 'MlButton',
// 声明props的具体定义
props: buttonProps,
setup(props: ButtonProps, { slots }) {
// 保持响应
const { type, size, disabled, block } = toRefs(props)
// 数据写在setup函数中
return () => {
// 要渲染的内容写在渲染函数中
const defaultSlot = slots.default ? slots.default() : '按钮'
const blockCls = block.value ? 'ml-btn--block' : ''
return (
<button
disabled={disabled.value}
class={`ml-btn ml-btn--${type.value} ml-btn--${size.value} ${blockCls}`}
>
{defaultSlot}
</button>
)
}
}
})
3、写测试文件button -> test -> button.test.ts
import { render } from '@testing-library/vue'
import Button from '../src/button'
// base功能
test('should work', () => {
// 希望不传值得到一个按钮
const { getByRole } = render(Button)
getByRole('button')
})
// 测试插槽功能{defaultSLots} = 按钮
test('default slot should be 按钮', () => {
// 通过文本获取
const { getByText } = render(Button)
getByText('按钮')
})
// 插槽能正常工作吗
test('slot should work', () => {
// 通过文本获取
const { getByText } = render(Button, {
slots: {
default() {
return 'confirm'
}
}
})
getByText('confirm')
})
// 测试类型
test('default type should be secondary', () => {
// 测试默认
const { getByRole } = render(Button)
const button = getByRole('button')
expect(button.classList.contains('ml-btn--secondary')).toBe(true)
})
test('prop type should work', () => {
// 测试默认
const { getByRole } = render(Button, {
props: {
type: 'primary'
}
})
const button = getByRole('button')
expect(button.classList.contains('ml-btn--primary')).toBe(true)
})
4、参考vitest官方文档
四、为什么使用vitest
Vite是一个构建工具,旨在为现代 web 项目提供更快、更精简的开发体验,它开箱即用,支持常见的 web 模式、glob导入和 SSR 等功能。它的许多插件和集成正在促进一个充满活力的生态系统。但这导致了一个新问题:如何在Vite上编写单元测试。将Jest等框架与Vite一起使用,导致Vite和Jest之间有很多重复的配置,而 Vitest 解决了这一问题,它消除了为我们的应用程序编写单元测试所需的额外配置。Vitest 使用与 Vite 相同的配置,并在开发、构建和测试时共享一个共同的转换管道。它还可以使用与 Vite 相同的插件API进行扩展,并与Jest的API兼容,以方便从Jest迁移,而不需要做很多重构工作。因此,Vitest 的速度也非常快。