vitest 实战
在看了文章在任何一个项目中快速引入 vitest 后,我们来看看 vitest 的实战应用。
配置环境
vitest 默认的环境为 node,所以没有 document、window 这些全局对象。如果像让 vitest 的环境变为浏览器,可以使用 jsdom。
js
import { defineConfig } from 'vitest/config';
import path from 'path';
export default defineConfig({
test: {
environment: 'jsdom'
}
});配置路径别名
js
import { defineConfig } from 'vitest/config';
import path from 'path';
export default defineConfig({
test: {
// ...
include: ['test/*.{test,spec}.?(c|m)[jt]s?(x)'],
alias: [
{
find: '@',
replacement: path.resolve(__dirname, 'src')
}
],
environment: 'jsdom'
}
});配置断言 api 不用导入

为了可以让全局 API 支持 Typescript,需要将 vitest/globals 添加到 tsconfig.json 中的 types 选项中
json
// tsconfig.json
{
"compilerOptions": {
"types": ["vitest/globals"]
}
}断言
某个对象或数组拥有某个结构
会递归比较。
ts
import { expect, test } from 'vitest'
const stockBill = {
type: 'apples',
count: 13,
}
const stockMary = {
type: 'apples',
count: 13,
}
test('stocks have the same properties', () => {
expect(stockBill).toEqual(stockMary)
})
test('stocks are not the same', () => {
expect(stockBill).not.toBe(stockMary)
})断言某个值不为 undefined
js
expect('').toBeDefined()
expect({}).toBeDefined()测试异步代码
可以使用 async、await 测试异步代码
js
test('the data is peanut butter', async () => {
const data = await fetchData();
expect(data).toBe('peanut butter');
});
test('the fetch fails with an error', async () => {
expect.assertions(1);
try {
await fetchData();
} catch (e) {
expect(e).toMatch('error');
}
})断定字符串包含某个字符序列
ts
test('toContain', () => {
const str = 'ABCD'
expect(str).toContain('AB')
})断定数组中包含某个元素
断定一个数组中包含元素字符串 1。
ts
test('toContain', () => {
const arr1 = ['1',2,'c']
// ok
expect(arr1).toContain('1')
})断定数组中包含一个与给定值相同结构的元素
ts
test('toContainEqual', () => {
const arr = [1, 2, 3, {a:1,b:2}]
// 错误
// expect(arr).toContainEqual({a:1})
// 成功
expect(arr).toContainEqual({a:1,b:2})
})测试覆盖率
Vitest 通过 v8 支持原生代码覆盖率,通过 istanbul 支持检测代码覆盖率。
在 vites.config.ts 中配置覆盖率提供者:
js
coverage: {
provider: 'v8' // 'istanbul'。默认 v8。
},然后下载依赖。如果不下载,在跑覆盖率的时候也会提醒你下载。
shell
pnpm i -D @vitest/coverage-v8然后配置一个脚本,跑覆盖率:
json
"coverage": "vitest run --coverage"执行脚本后:

其中它们每个字段代表的含义如下
- %stmts 是语句覆盖率(statement coverage):是不是每个语句都执行了?
- %Branch 分支覆盖率(branch coverage):是不是每个 if 代码块都执行了?
- %Funcs 函数覆盖率(function coverage):是不是每个函数都调用了?
- %Lines 行覆盖率(line coverage):是不是每一行都执行了?
断定某个对象有哪些键值对
ts
expect(getHashAndParam(windowLocationUrl)).toEqual({
vConsole: '1',
key: 'DSFLSDFSDFSCDSDF',
xcxFlag: 'mallhome'
})