TDesign在vitest的实践示例详解

目录
  • 起源
  • 痛点与现状
  • vitest
  • 迁移
    • 配置文件改造
    • 开发环境
  • 集成测试
    • ssr 环境
    • csr 环境
  • 配置文件
  • 兼容性
  • 结果
    • CI测试速度提升
    • 更清爽的日志信息

起源

tdesign-vue-nextCI 流程中,单元测试模块的执行效率太低,每次在单元测试这个环节都需要花费 6m 以上。加上依赖按照,lint 检查等环节,需要花费 8m 以上。

加上之前在单元测试这一块只是简单的处理了一下,对开发者提交的组件也没有相应的要求,只是让它能跑起来就好。另一方面单元测试目前是 TD 发布正式版的一个卡点,所以准备对其进行一次梳理和重构,为后续的重点工作做准备。

痛点与现状

  • 单元测试执行效率太低,上面已经讲到了,这个速度是无法忍受。
  • 单元测试规范不明确,开发者没有对应的单测规范可以遵循,不知道怎么写。
  • 单元测试中 snapshot 占据了大多数,每个组件的单元测试中其所有 demo 都做了一次 snapshot。这部分的代码由脚本输出。在一定程度上属于集成测试,但执行过程融合在人工写的单元测试当中,需要做集成测试的整合。

vitest

最开始注意到 vitest 是在 evan you 的分享里面。vitest 的特性如下:

  • Vite 的配置、转换器、解析器和插件通用,免去了额外对 jest 的配置
  • TypeScript / JSX 支持开箱即用的,像写组件一样写测试
  • 多线程通过 tinypool 使用 Worker 线程尽可能多地并发运行测试。隔离了每个测试文件的运行环境,因此一个文件中的运行环境改变不会影响其他文件。
  • watch 模式下极速热更,在单元测试开发时更友好
  • Jest 几乎相同的 API,极少量的差异
  • 更清晰的 C8 生成测试覆盖率
  • 源码内联测试
  • 非常酷的 GUI

迁移

配置文件改造

依赖,上面说到,vitest 的配置文件和 vite 的配置文件共用,且插件也是共用,所以不需要像配置 jest 一样去配置 babel-jest, vue-jest, jest-serializer-vue 这些插件。

开发环境

vitest 中开发环境的执行命令

vitest --config site/vite.config.js 

单测开发的过程中,需要过滤对应的测试文件,则只需要加上对应的文件路径即可,具体如下:

#执行button组件的单测
vitest --config site/vite.config.js button
#执行button的index.test.jsx测试文件
vitest --config site/vite.config.js button/index.test.jsx 

另外还有 GUI 的选项

vitest --config site/vite.config.js --ui

集成测试

之前我们继承测试环境有两套 ssr 环境和 csr 环境。

ssr 环境

ssr 环境的测试需要做一个 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环境的配置
config.global.createSSRApp = (comp) => {
  const app = createApp(comp);
  app.config.globalProperties.$route = {};
  app.use(TDesign);
  const html = renderToString(app);
  return html;
};

之前的执行环境是 commonjs 引入组件使用的是 require, 在 vite 中需要替换为 es 规范的 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 环境

csr 环境的集成测试在之前使用的是脚本输出一个如下的标准文件,分散在每个组件的单元测试里面。这样做影响单元测试的执行效率,对每个组件都开一个 describe, 这些代码会影响单元测试的代码结构。所以合并在一个文件执行是最合理的。其实现思路与ssr基本一致,只是 render 不一样而已。

/**
 * 该文件为由脚本 `npm run test:demo` 自动生成,如需修改,执行脚本命令即可。请勿手写直接修改,否则会被覆盖
 */
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.jstest 选项即可.

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 中的函数,切换到 vi,其他问题没有遇到。

before

const fn = jest.fn();

after

import { vi } from 'vitest';
const fn = vi.fn();

结果

CI测试速度提升

CI 中从原来的 6m 提升到 2m30, 执行效率提升百分之 60%,在开发机的执行效率更高(不同配置的机器执行效率不同,用 ci 中的标准执行做对比测试)。

更清爽的日志信息

jest 这一部分的 log 只是单个组件的日志,而整个 log 记下来是非常长的,导致我们在开发中会忽略掉很多日志的告警。本地的 terminal 输出的长度是有限制的。而 vitestlog 则非常清爽。

源码传送门

以上就是TDesign在vitest的实践示例详解的详细内容,更多关于TDesign在vitest实践的资料请关注我们其它相关文章!

(0)

相关推荐

  • 如何在React项目中使用AntDesign

    目录 0.前言 1.AntDesign是什么? 2.AntDesign如何使用? 3.如何具体使用AntDdesign的组件 3-1.如何使用 antd 的Table组件 3-2.如何使用 antd 的Button组件 4.后续 0.前言 我们在后台管理系统React项目开发中会有Table表格.Form表单.List列表.Button按钮等组件,这个时候我们可以使用AntDesign来减少开发中不必要的样式问题. 1.AntDesign是什么? Ant Design 是一个 UI 设计语言,是

  • vue在antDesign框架或elementUI框架组件native事件中触发2次问题

    目录 vue在antDesign或elementUI组件native事件中触发2次 运用ant-design-vue组件库,且在项目中遇到的问题 难以改变的默认样式 让通知提醒框的内容自动换行 table组件表格出现时间时,格式问题 vue在antDesign或elementUI组件native事件中触发2次 打印event.target 核心思想是设置下event.target的过滤 运用ant-design-vue组件库,且在项目中遇到的问题 难以改变的默认样式 可能大家在运用到组件库的时候

  • Vue中Table组件行内右键菜单实现方法(基于 vue + AntDesign)

    最近做的一个项目是基于 vue + AntDesign 的.由于项目要求,需要在 Table 组件的行内点右键的时候弹出菜单.在线演示地址及最终效果图如下: 在线演示地址>> 首先新建一个Table组件的实例: <a-table :columns="columns" :rowKey="record => { return record.INDEX;}" :dataSource="tableData" /> ... c

  • TDesign在vitest的实践示例详解

    目录 起源 痛点与现状 vitest 迁移 配置文件改造 开发环境 集成测试 ssr 环境 csr 环境 配置文件 兼容性 结果 CI测试速度提升 更清爽的日志信息 起源 在 tdesign-vue-next 的 CI 流程中,单元测试模块的执行效率太低,每次在单元测试这个环节都需要花费 6m 以上.加上依赖按照,lint 检查等环节,需要花费 8m 以上. 加上之前在单元测试这一块只是简单的处理了一下,对开发者提交的组件也没有相应的要求,只是让它能跑起来就好.另一方面单元测试目前是 TD 发布

  • 微服务架构之服务注册与发现实践示例详解

    目录 1 服务注册中心 4种注册中心技术对比 2 Spring Cloud 框架下实现 2.1 Spring Cloud Eureka 2.1.1 创建注册中心 2.1.2 创建客户端 2.2 Spring Cloud Consul 2.2.1 Consul 的优势 2.2.2 Consul的特性 2.2.3 安装Consul注册中心 2.2.4 创建服务提供者 3 总结 微服务系列前篇 详解微服务架构及其演进史 微服务全景架构全面瓦解 微服务架构拆分策略详解 微服务架构之服务注册与发现功能详解

  • react后台系统最佳实践示例详解

    目录 一.中后台系统的技术栈选型 1. 要做什么 2. 要求 3. 技术栈怎么选 二.hooks时代状态管理库的选型 context redux recoil zustand MobX 三.hooks的使用问题与解决方案 总结 一.中后台系统的技术栈选型 本文主要讲三块内容:中后台系统的技术栈选型.hooks时代状态管理库的选型以及hooks的使用问题与解决方案. 1. 要做什么 我们的目标是搭建一个适用于公司内部中后台系统的前端项目最佳实践. 2. 要求 由于业务需求比较多,一名开发人员需要负

  • Gradle 依赖切换源码实践示例详解

    目录 引言 1.一般的修改办法 2.通过 Gradle 脚本动态修改依赖 2.1 配置文件和工作流程抽象 2.2 为项目动态添加子工程 2.3 使用子工程替换依赖 2.4 注意事项 总结 引言 最近,因为开发的时候经改动依赖的库,所以,我想对 Gradle 脚本做一个调整,用来动态地将依赖替换为源码.这里以 android-mvvm-and-architecture 这个工程为例.该工程以依赖的形式引用了我的另一个工程 AndroidUtils.在之前,当我需要对 AndroidUtils 这个

  • ReactQuery系列React Query 实践示例详解

    目录 引言 客户端状态 vs 服务端状态 React Query 关于默认行为的解释 使用React Query DevTools 把query key理解成一个依赖列表 一个新的缓存入口 把服务端状态和客户端状态分开 enabled属性是很强大的 创建自定义hook 引言 当2018年GraphQL特别是Apolllo Client开始流行之后,很多人开始认为它将替代Redux,关于Redux是否已经落伍的问题经常被问到. 我很清晰地记得我当时对这些观点的不理解.为什么一些数据请求的库会替代全

  • Flink实践Savepoint使用示例详解

    目录 一.背景 Snapshot 状态快照 分布式快照 Checkpoint & Savepoint 二.Flink on yarn 如何使用 savepoint 附录:一致性语义 确保精确一次(exactly once) 端到端精确一次 一.背景 什么是 savepoint,为什么要使用 savepoint ? 保障 flink 作业在 配置迭代.flink 版本升级.蓝绿部署中的数据一致性,提高容错.降低恢复时间: 在此之前引入几个概念: Snapshot 状态快照 Flink 通过状态快照

  • Java数组的声明与创建示例详解

    今天在刷Java题的时候,写惯了C++发现忘记了Java数组的操作,遂把以前写的文章发出来温习一下. 首先,数组有几种创建方式? Java程序中的数组必须先进行初始化才可以使用,所谓初始化,就是为数组对象的元素分配内存空间,并为每个数组元素指定初始值,而在Java中,数组是静态的,数组一旦初始化,长度便已经确定,不能再随意更改. 声明数组变量 首先必须声明数组变量,才能在程序中使用数组.下面是声明数组变量的语法: dataType[] arrayRefVar; // 首选的方法 或 dataTy

  • R语言时间序列TAR阈值自回归模型示例详解

    为了方便起见,这些模型通常简称为TAR模型.这些模型捕获了线性时间序列模型无法捕获的行为,例如周期,幅度相关的频率和跳跃现象.Tong和Lim(1980)使用阈值模型表明,该模型能够发现黑子数据出现的不对称周期性行为. 一阶TAR模型的示例: σ是噪声标准偏差,Yt-1是阈值变量,r是阈值参数, {et}是具有零均值和单位方差的iid随机变量序列. 每个线性子模型都称为一个机制.上面是两个机制的模型. 考虑以下简单的一阶TAR模型: #低机制参数 i1 = 0.3 p1 = 0.5 s1 = 1

  • Python数学建模StatsModels统计回归之线性回归示例详解

    目录 1.背景知识 1.1 插值.拟合.回归和预测 1.2 线性回归 2.Statsmodels 进行线性回归 2.1 导入工具包 2.2 导入样本数据 2.3 建模与拟合 2.4 拟合和统计结果的输出 3.一元线性回归 3.1 一元线性回归 Python 程序: 3.2 一元线性回归 程序运行结果: 4.多元线性回归 4.1 多元线性回归 Python 程序: 4.2 多元线性回归 程序运行结果: 5.附录:回归结果详细说明 1.背景知识 1.1 插值.拟合.回归和预测 插值.拟合.回归和预测

  • TensorFlow卷积神经网络AlexNet实现示例详解

    2012年,Hinton的学生Alex Krizhevsky提出了深度卷积神经网络模型AlexNet,它可以算是LeNet的一种更深更宽的版本.AlexNet以显著的优势赢得了竞争激烈的ILSVRC 2012比赛,top-5的错误率降低至了16.4%,远远领先第二名的26.2%的成绩.AlexNet的出现意义非常重大,它证明了CNN在复杂模型下的有效性,而且使用GPU使得训练在可接受的时间范围内得到结果,让CNN和GPU都大火了一把.AlexNet可以说是神经网络在低谷期后的第一次发声,确立了深

随机推荐