如何打造一个vite3+vue3.2+ts的单元测试环境

前言

随着vue3和vue-test-utlis的正式发布,伴随着新的api和新的打包工具vite,新的单测方案也呼之欲出,在阅读了@Kagol老师文章,通过自己摸索把最新版本的单测环境分享给大家,本文介绍了如何去打造vue3在vite中的组件测试环境demo

topic

本文topic分为以下

  • 初始化vite环境
  • JSX支持
  • jest配置
  • 运行单元测试

1初始化vite环境

1.1 创建vite

官方文档

$ yarn create vite
//OR
$ npm create vite@latest

这里推荐node版本大于16.0.0以上即可

//测试demo版本
@GavindeMacBook-Pro vue-devui % node -v
v16.17.1

1.2 选择对应创建模板

✔ Project name: [随意取自己喜欢的名字]test-demo
? Select a framework: › - Use arrow-keys. Return to submit.
    Vanilla
❯   Vue
    React
    Preact
    Lit
    Svelte
    Others
? Select a variant: › - Use arrow-keys. Return to submit.
    JavaScript
❯   TypeScript
    Customize with create-vue ↗
    Nuxt ↗

按cli脚本一步步创建vite+vue+ts环境,cd进入创建好的目录

1.3 配置tsconfig

一般不需要配置,需要配置路径别名或者其他的特殊配置下面官网查询

「typescript官方」

1.4 启动项目编写测试组件

启动前先安装依赖

//进入终端
yarn add
//or
npm i

启动项目

npm run dev
//or
yarn dev

如果正常弹出浏览器初始化画面第一步就完成了

2 JSX支持

2.1 插件支持

vite天然支持的jsx,但是需要安装官方给的插件才可以完美的使用tsx/jsx

yarn add -D @vitejs/plugin-vue-jsx

随后在项目根目录下vite.config.ts中加载这个插件

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import setupJSX from '@vitejs/plugin-vue-jsx'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(),setupJSX()],
})

2.2 编写tsx组件demo

测试demo组件

import type { PropType, ExtractPropTypes, SetupContext } from 'vue';
import { defineComponent } from 'vue'


type ButtonData = Array<{
    class: string
    title: string
    clickEvent: (e: MouseEvent) => void
}>;
export const buttonDataProps = {
    data: {
        type: Array as PropType<ButtonData>,
        default: [],
        required: true
    },
} as const;

export type ButtonDataProps = ExtractPropTypes<typeof buttonDataProps>;
export default defineComponent({
    name: 'GButton',
    props: buttonDataProps,
    emits: [],
    setup(props: ButtonDataProps, ctx: SetupContext) {
        const renderButton = () => {

            return props.data.map(item => <button class={item.class} onClick={item.clickEvent}>{item.title}</button>)
        }
        return () => (<div class="btn-test">
            {renderButton()}
        </div>)
    }
});

// /src/components/button.tsx

APP父组件

<script setup lang="ts">
import ButtonIcon from './components/button'
const data=[{
      title:'A',
      class:'abc btn',
      clickEvent:(e:MouseEvent)=>{
        console.log(e);  
      }
    },
    {
      title:'B',
      class:'abc',
      clickEvent:(e:MouseEvent)=>{
        console.log(e);
      }
    }]
</script>
<template>
  <div>
    <ButtonIcon  :data="data"></ButtonIcon>
  </div>
</template>
// ./App.vue

页面显示效果
按钮1.png

3 运行单元测试&jest配置

3.1 引入Jest

yarn add -D jest @types/jest
//or
npm i -D jest @types/jest

3.2 配置脚本化命令

"scripts": { 
    "dev": "vite", 
    "build": "vue-tsc --noEmit && vite build", 
    "serve": "vite preview", 
    "test": "jest" 
 }
//./package.json

3.3 引入 @vue/test-utils

当我们测试我们的组件渲染时候,需要用的@vue/test-utils 他可以为我们的模拟出组件的渲染状态

yarn add -D @vue/test-utils
//or
npm i -D @vue/test-utils

4 运行单元测试

4.1 编写测试用例

建立路径编写测试用例

import { ComponentPublicInstance } from 'vue';
import {  mount, VueWrapper } from '@vue/test-utils';
import ButtonIcon from '../button';
describe('btn-test', () => {
  let wrapper: VueWrapper<ComponentPublicInstance>;
  it('btn-test init render', async () => {
    wrapper = mount({
      setup() {
        const data = [{
          title: 'A',
          class: 'abc btn',
          clickEvent: (e: MouseEvent) => {
            console.log(e);
          }
        },
        {
          title: 'B',
          class: 'abc',
          clickEvent: (e: MouseEvent) => {
            console.log(e);
          }
        }]
        return () => {
          return <ButtonIcon data={data}
          />;
        };
      },
    });
    console.log(wrapper.element);
    // todo
    expect(wrapper.classes()).toContain('btn-test');//测试是否通过是否有class名
    expect(wrapper.element.childElementCount).toBe(10);//测试通过存在10个子类
  })
})
// /src/components/__tests__

4.2 运行测试脚本

// test指令会直接寻找路径中有__test__的目录中的*.spec的测试文件
yarn test //运行
4.2.1 运行报错

报错.png
大概意思是当前的模版语法缺少babel或者其他插件的支持,我们需要配置jest.config引入babel插件

4.2.2 配置jest.config

//CJS模块规范 老版本 xxx不推荐
module.exports =  {

  transform: {
    '^.+\\.(ts|tsx|js|jsx)$': [
      'babel-jest',
      {
        presets: [['@babel/preset-env', { targets: { node: 'current' } }], ['@babel/preset-typescript']],
        plugins: ['@vue/babel-plugin-jsx'],
      },
    ],
  },
  testMatch: ['**/**/*.spec.(ts|tsx)'],
  moduleFileExtensions: ['js', 'json', 'ts', 'tsx'],
  testPathIgnorePatterns: ['/node_modules/'],
};


//ESM模块规范 新版jest支持  推荐
export default {

  transform: {
    '^.+\\.(ts|tsx|js|jsx)$': [
      'babel-jest',
      {
          presets: [['@babel/preset-env', { targets: { node: 'current' } }]['@babel/preset-typescript']],
        plugins: ['@vue/babel-plugin-jsx'],
      },
    ],
  },
  testMatch: ['**/**/*.spec.(ts|tsx)'],
  moduleFileExtensions: ['js', 'json', 'ts', 'tsx'],
  testPathIgnorePatterns: ['/node_modules/'],
};
//./jest.config.js

4.2.3 引入babel插件

根据上文配置引入

yarn add -D @babel/preset-env @babel/preset-typescript  @vue/babel-plugin-jsx

4.3 运行后又一个报错

报错2.png
提示我们需要jsdom的环境插件

4.3.1 增加配置

安装jsdom插件

yarn add -D jest-environment-jsdom

配置增加

  testEnvironment: 'jest-environment-jsdom',
  testEnvironmentOptions: {
    customExportConditions: ["node", "node-addons"],
 },
//./src/jest.config.js

注意在新版本中如果不增加这个testEnvironmentOptions属性,会报找不到Vue错误,这个坑我踩了很久,囧!

4.4 再次运行

chenggong.png

已经能成功跑通这个测试。

总结

以上就是整个vute-test-utils和jest单测环境搭建的全过程,在这里感谢@Kagol老师和@DEV-UI团队的关于单测试的分享,需要了解详细流程的小伙伴可以关注以下链接

【我要做开源】给 vue devui 组件库项目增加单元测试

关于我

一部分demo和笔记我已经放在了我的github上大家想要可以直接访问下载源码Github

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容