编写测试
容易出现的问题
- 手动测试,新建一堆不同属性的组件
- 肉眼观测,或是浏览器手动点击,刷新
- 更新代码,要再次进行手动测试
项目需要测试吗?
为了代码的健壮和可维护性,我们需要编写测试代码
TDD的开发方式
TDD(Test-Driven Development)测试驱动开发,是一种软件开发方法,它强调在编写代码之前先编写测试用例,然后通过不断编写和运行测试用例来驱动代码的开发。
步骤:
- 编写测试用例
- 运行测试用例
- 编写代码:根据测试用例的要求,编写代码并实现功能
- 运行测试用例
- 重构代码(可选)
- 重复以上步骤
优点:
- 自动化完成流程,保证代码的运行结果
- 更早发现 bug
- 重构和升级更加容易和可靠
组件化框架(React、Vue)非常适合写单元测试
- 组件化,独立单元,互不影响
- 属性和界面的映射,固定输入,固定输出
- 单向数据流
- 状态管理工具的 store 可以单独写测试
测试框架
需要选取两种测试工具
- 通用的测试框架
- Mocha
- Jest
- Vitest
- 针对对应库的测试库
文档地址 https://vitest.dev/guide/why.html
Vitest 优点
- 基于 Vite 而生,和 Vite 完美配合,共享一个生态系统
- 兼容 Jest 语法
- HMR for tests
- ESM、TS、JSX 原生支持
测试框架的几大功能
- 断言
- 内置 Chai 以及兼容 Jest expect 的 API
- Mock
- 代码覆盖率
- https://vitest.dev/guide/mocking.html
- 可以使用 c8 或者 istanbul
- Snapshot
- 兼容 Jest
基于 Vue 的测试工具
- vue-test-utils https://test-utils.vuejs.org/guide/
- vue-testing-library https://testing-library.com/docs/vue-testing-library/intro
- Vitest 的配置文件 https://vitest.dev/config
vue-test-utils
- 挂载 mount
- 修改vitest配置,支持DOM
- environment: 'jsdom'
- query
- find() / get()
- findAll()
- findComponent()
- 内容 / 属性
- text()
- html()
- classes()
- attributes()
- stub 模拟子组件
VNode相关
在测试一些带有 slots 的组件时需要用到 https://cn.vuejs.org/guide/extras/rendering-mechanism.html
Virtual DOM 是一种虚拟的,保存在内存中的数据结构,代表 UI 表现,和真实 DOM 节点保持同步。
Render pipeline
- compile Vue 组件的 template 会被编译成 render function, 一个可以返回 VDOM 树的函数
- Mount 执行 render function 遍历虚拟 DOM 树,生成真正的 DOM 节点
- Patch 当组件中任何响应式对象依赖发生变化时,执行更新操作。生成新的虚拟节点树。Vue 内部会遍历新的虚拟节点树,和旧树做对比,然后执行必要的更新操作
优点:
- 可以使用一种更方便的方式,不必修改真实的 DOM
- 更新效率更高,计算需要最小化操作,并完成更新
创建 VNode
https://cn.vuejs.org/guide/extras/render-function.html
h 和 createVnode 都可以创建 vnode, h 是 hyperscript 的缩写(意为 JavaScript that produces HTML),很多 VDOM 的实现都使用这个函数名称。还有个就是 createVnode,名称更形象,两者用法是一样的
js
import { h, createVnode } from 'vue'
const vnode = h(
'div', // type
{ id: 'foo', class: 'bar' }, // props
[
// children
]
)
运用vitest提供的钩子函数增加效率
- beforeAll 所有测试用例开始前的钩子
- beforeEach 每个测试用例开始之前的钩子
- afterAll 所有测试用例执行完后
- afterEach 每个测试用例执行完后
可配合 test.skip test.only 等修饰符