TDesign在vitest的實踐示例詳解
起源
在 tdesign-vue-next 的 CI 流程中,單元測試模塊的執(zhí)行效率太低,每次在單元測試這個環(huán)節(jié)都需要花費 6m 以上。加上依賴按照,lint 檢查等環(huán)節(jié),需要花費 8m 以上。
加上之前在單元測試這一塊只是簡單的處理了一下,對開發(fā)者提交的組件也沒有相應的要求,只是讓它能跑起來就好。另一方面單元測試目前是 TD 發(fā)布正式版的一個卡點,所以準備對其進行一次梳理和重構,為后續(xù)的重點工作做準備。

痛點與現(xiàn)狀
- 單元測試執(zhí)行效率太低,上面已經(jīng)講到了,這個速度是無法忍受。
- 單元測試規(guī)范不明確,開發(fā)者沒有對應的單測規(guī)范可以遵循,不知道怎么寫。
- 單元測試中
snapshot占據(jù)了大多數(shù),每個組件的單元測試中其所有demo都做了一次snapshot。這部分的代碼由腳本輸出。在一定程度上屬于集成測試,但執(zhí)行過程融合在人工寫的單元測試當中,需要做集成測試的整合。
vitest
最開始注意到 vitest 是在 evan you 的分享里面。vitest 的特性如下:
- 與
Vite的配置、轉換器、解析器和插件通用,免去了額外對jest的配置 - 對
TypeScript / JSX支持開箱即用的,像寫組件一樣寫測試 - 多線程通過
tinypool使用Worker線程盡可能多地并發(fā)運行測試。隔離了每個測試文件的運行環(huán)境,因此一個文件中的運行環(huán)境改變不會影響其他文件。 watch模式下極速熱更,在單元測試開發(fā)時更友好- 與
Jest幾乎相同的API,極少量的差異 - 更清晰的
C8生成測試覆蓋率 - 源碼內聯(lián)測試
- 非??岬?
GUI


遷移
配置文件改造
依賴,上面說到,vitest 的配置文件和 vite 的配置文件共用,且插件也是共用,所以不需要像配置 jest 一樣去配置 babel-jest, vue-jest, jest-serializer-vue 這些插件。
開發(fā)環(huán)境
vitest 中開發(fā)環(huán)境的執(zhí)行命令
vitest --config site/vite.config.js
單測開發(fā)的過程中,需要過濾對應的測試文件,則只需要加上對應的文件路徑即可,具體如下:
#執(zhí)行button組件的單測 vitest --config site/vite.config.js button #執(zhí)行button的index.test.jsx測試文件 vitest --config site/vite.config.js button/index.test.jsx
另外還有 GUI 的選項
vitest --config site/vite.config.js --ui
集成測試
之前我們繼承測試環(huán)境有兩套 ssr 環(huán)境和 csr 環(huán)境。
ssr 環(huán)境
對 ssr 環(huán)境的測試需要做一個 setup 用來做組件 render,此部分和之前保持一致。
ssr-setup
import { config } from '@vue/test-utils';
import { createApp } from 'vue';
import { renderToString } from '@vue/server-renderer';
import TDesign from '@/src/index';
config.global.plugins = [TDesign];
// global掛載createSSRApp方法,掛載render環(huán)境的配置
config.global.createSSRApp = (comp) => {
const app = createApp(comp);
app.config.globalProperties.$route = {};
app.use(TDesign);
const html = renderToString(app);
return html;
};之前的執(zhí)行環(huán)境是 commonjs 引入組件使用的是 require, 在 vite 中需要替換為 es 規(guī)范的 import
const demo = require(`../.${file}`);ssr.test.js
import glob from 'glob';
import MockDate from 'mockdate';
import { config } from '@vue/test-utils';
MockDate.set('2020-12-28 00:00:00');
function runTest() {
const files = glob.sync('./examples/**/demos/*.vue');
const { createSSRApp } = config.global;
describe('ssr snapshot test', () => {
files.forEach((file) => {
it(`ssr test ${file}`, async () => {
const demo = await import(`../.${file}`); //此部分
const realDemoComp = demo.default ? demo.default : demo;
const html = await createSSRApp(realDemoComp);
expect(html).toMatchSnapshot();
});
});
});
}
runTest();csr 環(huán)境
csr 環(huán)境的集成測試在之前使用的是腳本輸出一個如下的標準文件,分散在每個組件的單元測試里面。這樣做影響單元測試的執(zhí)行效率,對每個組件都開一個 describe, 這些代碼會影響單元測試的代碼結構。所以合并在一個文件執(zhí)行是最合理的。其實現(xiàn)思路與ssr基本一致,只是 render 不一樣而已。
/**
* 該文件為由腳本 `npm run test:demo` 自動生成,如需修改,執(zhí)行腳本命令即可。請勿手寫直接修改,否則會被覆蓋
*/
import { mount } from '@vue/test-utils';
import baseVue from '@/examples/affix/demos/base.vue';
import containerVue from '@/examples/affix/demos/container.vue';
const mapper = {
baseVue,
containerVue,
};
describe('Affix', () => {
Object.keys(mapper).forEach((demoName) => {
it(`Affix ${demoName} demo works fine`, () => {
const wrapper = mount(mapper[demoName]);
expect(wrapper.element).toMatchSnapshot();
});
});
});csr.test.js
import glob from 'glob';
import MockDate from 'mockdate';
import { mount } from '@vue/test-utils';
MockDate.set('2020-12-28 00:00:00');
function runTest() {
const files = glob.sync('./examples/**/demos/*.vue');
describe('csr snapshot test', () => {
files.forEach((file) => {
it(`csr test ${file}`, async () => {
const demo = await import(`../.${file}`);
const realDemoComp = demo.default ? demo.default : demo;
realDemoComp.name = `test-csr-${realDemoComp.name}`;
const wrapper = mount(realDemoComp);
expect(wrapper.element).toMatchSnapshot();
});
});
});
}
runTest();配置文件
vitest 的配置文件如下,下面這一段 config 只需要掛在 vite.config.js 的 test 選項即可.
const testConfig = {
include:
process.env.NODE_ENV === 'test-snap'
? ['test/snap/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}']
: ['test/unit/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
globals: true,
environment: 'jsdom',
testTimeout: 5000,
setupFiles: process.env.NODE_ENV === 'test-snap' ? path.resolve(__dirname, '../script/test/test-setup.js') : '',
transformMode: {
web: [/\.[jt]sx$/],
},
coverage: {
reporter: ['text', 'json', 'html'],
},
};兼容性
因為我們老的測試方案基于 jest,相應的 API 都有。所以在遷移過程中,兼容性問題基只有一些從 jest 中的函數(shù),切換到 vi,其他問題沒有遇到。
before
const fn = jest.fn();
after
import { vi } from 'vitest';
const fn = vi.fn();結果
CI測試速度提升
在 CI 中從原來的 6m 提升到 2m30, 執(zhí)行效率提升百分之 60%,在開發(fā)機的執(zhí)行效率更高(不同配置的機器執(zhí)行效率不同,用 ci 中的標準執(zhí)行做對比測試)。

更清爽的日志信息

jest 這一部分的 log 只是單個組件的日志,而整個 log 記下來是非常長的,導致我們在開發(fā)中會忽略掉很多日志的告警。本地的 terminal 輸出的長度是有限制的。而 vitest 的 log 則非常清爽。
以上就是TDesign在vitest的實踐示例詳解的詳細內容,更多關于TDesign在vitest實踐的資料請關注腳本之家其它相關文章!
相關文章
Vue iview-admin框架二級菜單改為三級菜單的方法
這篇文章主要介紹了Vue iview-admin框架二級菜單改為三級菜單的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
el-select選擇器組件下拉框增加自定義按鈕的實現(xiàn)
本文主要介紹了el-select選擇器組件下拉框增加自定義按鈕的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-07-07
el-table 表格最大高度max-height的問題解決
在工作中遇到了多個滾動條的情況,是因為el-table的max-height設置為固定值導致的,本文主要介紹了el-table 表格最大高度max-height的問題解決,具有一定的參考價值,感興趣的可以了解一下2024-07-07

