糯麦 NurMai

400-158-5662

糯麦科技

/

新闻资讯

/

技术讨论

/

Vite 1.0 正式发布:Vue 团队打造的下一代前端开发工具!

Vite 1.0 正式发布:Vue 团队打造的下一代前端开发工具!

原创 新闻资讯

于 2023-12-07 10:53:42 发布

18733 浏览

Vue 团队于12月5日正式发布了下一代测试框架 Vitest 1.0版本。Vitest 自2021年12月推出以来,经过两年的快速发展,目前在 npm 的下载量已经达到了每周250万次,并且还在呈现快速增长的趋势,Github Star 数量达到了10.7k。


1.jpg


Vitest 是什么?

Vitest 是一个原生支持 Vite 的测试框架。Vitest 以其快速、简洁的测试解决方案脱颖而出,需要最少的配置。Vitest 与广泛采用的JavaScript测试框架 Jest 完美契合,并能无缝集成到 Vue 应用中。虽然它专为与 Vite 一起使用而设计,但Vitest也可以独立运行,在应用中提供了灵活性。由于 Vitest 和 Vite 使用相同的配置文件,因此将 Vitest 集成到 Vue 应用中很简单。


2.jpg


Vitest 的主要功能如下:

•  与 Vite 通用的配置、转换器、解析器和插件。

•  使用与你的应用程序相同的设置来运行测试!

•  智能文件监听模式,就像是测试的 HMR!

•  支持对 Vue、React、Svelte、Lit 等框架进行组件测试。

•  开箱即用的 TypeScript / JSX 支持

•  ESM 优先,支持模块顶级 await

•  通过 Tinypool 使用 Worker 线程尽可能多地并发运行

•  使用 Tinybench 来支持基准测试

•  套件和测试的过滤、超时、并发配置

•  支持 Workspace

•  Jest 的快照功能

•  内置 Chai 进行断言 + 与 Jest expect 语法兼容的 API

•  内置用于对象模拟(Mock)的 Tinyspy

•  使用 jsdom 或 happy-dom 用于 DOM 模拟

•  通过 v8 或 istanbul 来输出代码测试覆盖率

•  类似于 Rust 语言的源码内联测试

•  通过 expect-type 进行类型测试


Vitest 1.0 更新内容

重大变更

•  添加对pool和poolOptions的支持,移除旧标志

•  支持多个并行child_process

•  使快照更加美观

•  为子包设置vitest对等依赖范围

•  将最低 node 版本提升至 18,并匹配 Vite 5 的要求

•  移除已弃用的 node 加载器

•  将浏览器提供程序移到 @vitest/browser 包中

•  移除EnhancedSpy类型,弃用SpyInstance,改进模拟和 vi 文档

•  runner: 正确处理自定义任务,更新 runner hooks 命名


•  coverage:

  ▪  基于 glob 的覆盖率阈值

  ▪  使用transformMode和基于工作区项目的源映射

  ▪  默认启用 coverage.all


新功能

•  添加 Marko 示例,并包括 Marko 文件的代码覆盖率

•  更新magic-string

•  实现provide/inject API 以传输来自主线程的数据

•  改进expectTypeOf错误消息

•  添加test.sequential() api

•  允许自定义池

•  添加 --project 选项以限制正在运行的项目

•  benchmark:将importTinybench移动到runner中

•  browser:支持 "none" 提供程序,并更新lit示例以使用它

•  coverage:支持 /* v8 ignore... 忽略提示


•  expect:

  ▪  支持 expect.closeTo api

  ▪  ToContain可以处理classList和Node.contains

  ▪  通过href比较 URL 对象


•  snapshot:添加配置快照目录的选项

•  vite-node:支持 Vite 5 的import.meta.hot.off


•  vitest:

  ▪  暴露getBenchFn、getBenchOptions

  ▪  在测试期间运行类型检查

  ▪  过滤堆栈跟踪

  ▪  将execArgv暴露给不同的池


Vitest 尝鲜

准备工作

要想在 Vue 项目中运行自动化组件测试,首先要使用以下命令初始化一个 Vue 应用:

npm create vite@latest vue-app --template vue
cd vue-app
npm install

项目安装完成后,运行以下命令启动应用:

npm run dev

在浏览器中打开 http://127.0.0.1:5173/,即可看到应用程序成功运行。


接下来,使用以下命令来安装 Vitest:

npm install -D vitest

安装完成后,我们需要将 Vitest 添加到 package.json 文件中。在 package.json 文件中添加测试脚本:

"scripts": {
  // ...
   "test": "vitest",
 },

接下来,打开 vitest.config.js 文件并添加以下代码:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
 plugins: [vue()],
 test:{
   globals:true,
 }
})

将 globals 属性设置为 true 将允许在测试文件中访问 Vitest API,而无需导入它们。


Test Utils 是一个 Vue 测试库,提供了安装 Vue 组件并与之交互的方法。使用以下命令安装测试实用程序:

npm install --save-dev @vue/test-utils

我们应该能够在组件测试中模拟 DOM API。Vitest 目前支持happy-dom和jsdom。这里我们将使用 happy-dom。运行下面的命令来安装happy-dom:

npm install happy-dom@6.0.4

安装完成后,在 package.json 文件中的测试脚本中添加--dom:

"scripts": {
   // …
   "test": "vitest --dom", 
 },

另外,我们需要将 happy-dom 添加到 vite.config.js 文件中,以使其在测试文件中全局可用:

test:{
   // …
   environment: 'happy-dom',
 }


创建 Vue 组件

接下来,创建一个名为 GuessAge.vue 的简单组件,该组件使用户能够输入自己的姓名,并使用 Agify.io API 根据输入的姓名猜测用户的年龄。


在 src/components 文件夹中,创建一个 GuessAge.vue 文件并添加以下代码:

<template>
  <h1>{{ title }}</h1>
  <div class="card">
   <div style="width:400px;height:130px;margin-top:20px;border-style: dotted;" >
   <br>
    <span>名字: {{firstname}}</span> <br>
    <span>年龄: {{age}}</span> <br>

    </div><br><br>
     <label> 输入名字 </label><br>
     <input type="text" v-model="search" style="font-size:20px;border-radius:10px;" placeholder=" Name ..."> <br> <br>
    <button type="button" @click="getAge">猜年龄</button>
    <br> <br> <br>
    <input type="radio" value="pop"> <label>保存</label>
  </div>
</template>
<script setup>
import { ref } from 'vue'
defineProps({
  title: String
})
</script>
<script>
export default {
    data() {
        return {
            search:"",
            firstname:"",
            age:"",
        }
    },
    computed: {
       getAge() {
        fetch('https://api.agify.io/?name='+ this.search)
        .then(response => response.json())
        .then(data => {
            this.age = data.age
            this.firstname = data.name
            this.search=""
        })
        }
    }
}
</script>


测试 Vue 组件的 props 和函数

现在,我们需要为组件创建一个测试文件。根据命名约定,测试文件名必须以组件名称开头,以 .spec.js 或 .test.js 结尾。当测试多个组件时,每个组件都应该有一个测试文件。


在 Components 文件夹中创建一个名为 GuessAge.spec.js 的测试文件。该文件将包含 GuessAge 组件的简单测试脚本。让我们测试 GuessAge 组件,看看它在安装时是否接收到正确的 props。可以通过将以下代码添加到 GuessAge.spec.js 文件来测试挂载时 title 属性的值:

import {mount} from "@vue/test-utils";
import GuessAge from "../components/GuessAge.vue";
// import { expect, test } from "vitest";
const wrapper = mount(GuessAge);

it("testing GuessAge component props", async () => {
  expect(GuessAge.props.title).toContain("Guess User Age App");
});

从 @vue/test-utils 导入 mount,允许将组件包装到一个名为 Wrapper 的特殊对象中,它提供了各种测试选项。


注意:如果在 Vite 的配置文件中将globals的值设置为false,那么在测试文件中就应该添加 import { expect, test } from "vitest"。


运行以下命令以在监听模式下测试组件:

npm run test

3.jpg


我们还可以使用 toBe('function') 断言方法来检查应用中是否存在函数,如下所示:

it("Test if data is a function", () => {
  expect(typeof GuessAge.data).toBe("function");
});

可以在终端中看到以下内容:


4.jpg


使用快照测试用例

快照用于跟踪用户界面的变化。典型的快照测试用例会渲染一个UI组件,获取一个快照,并将其与测试文件旁边的参考快照文件进行比较。它将当前的UI状态与已建立的快照进行比较。如果当前状态与已建立状态不匹配,测试将失败。


要运行快照测试并跟踪UI的变化,需要在GuessAge.spec.js测试文件中添加以下代码:

test('snapshot UI testing', () => {
   const wrapper = mount(GuessAge,{});
   expect(wrapper.text()).toMatchSnapshot()
})

由于Vitest支持热模块重载,每次修改测试文件时都不必运行测试命令。可以在终端中看到以下内容:


5.jpg


模拟 HTTP 请求

在使用HTTP请求测试Vue组件时,我们首先需要模拟网络请求;否则,测试将失败。使用 Mock Service Worker (MSW) 进行模拟可以轻松地通过拦截测试中的请求来测试 HTTP 请求,而不需要更改任何应用程序代码。


使用以下命令来安装 MSW:

npm install msw --save-dev

我们需要在 GuessAge.spec.js 测试文件中导入以下两个依赖项才能使用 MSW:

import { setupServer } from 'msw/node'
import { rest } from 'msw'

通过在GuessAge.spec.js测试文件中添加以下代码来创建拦截HTTP请求的模拟服务器实例:

export const restHandlers = [
   rest.get('https://api.agify.io/', (req, res, ctx) => {
      return res(ctx.status(200), ctx.json([
         {
            age: 55,
            name: "tope"
         }
      ]))
   }),
]
const server = setupServer(...restHandlers)
// 在所有测试之前启动服务
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
// 在所有测试之后关闭服务
afterAll(() => server.close())
// 在每个测试后重置处理程序,对于测试隔离很重要
afterEach(() => server.resetHandlers())


测试点击事件

接下来检查应用中是否存在按钮,以及单击“猜年龄”按钮是否会在获取用户年龄后清除输入标签

test("有按钮", () => {
  expect(wrapper.find("button").exists()).toBe(true);
});

test("Button clicked", async () => {
   const ac = await wrapper.get("button").trigger("click")
   expect(wrapper.vm.search).toEqual("")
})

可以在终端中看到以下内容:


6.jpg


覆盖率测试

为了评估代码的效果和质量,Vitest支持通过c8和Istanbul实现本地代码覆盖率,从而对代码性能进行报告和分析。


为了配置和运行覆盖率测试,我们需要在vite.configure.js文件中添加以下内容:

export default defineConfig({
  plugins: [vue()],
  test:{
    globals:true,
    coverage: {
      provider: 'istanbul'
    },
    environment: 'happy-dom',
  }
})

此外,我们还需要在package.json文件中的脚本部分添加coverage,如下所示:

"scripts": {
  // ...
   "coverage": "vitest run --coverage"
 },

配置完成之后 ,接下来就使用以下命令安装 Istanbul:

npm i -D @vitest/coverage-istanbul

当执行以下命令时,测试文件将会运行,Vitest 将在终端上显示覆盖率报告:

npm run coverage


7.jpg


测试时间

在运行测试时,确保测试在合理的时间内完成非常重要。有时,一个测试可能需要太长时间才能完成,这可能会导致问题并延迟测试套件的运行。为了解决这个问题,Vitest提供了一个test-timeout选项,允许为测试设置超时时间。该选项指定了测试在超过最大时间限制之前可以完成的最长时间,否则将失败并显示超时错误。


可以使用以下命令为所有测试设置超时时间并替换默认时间:

npx vitest run --test-timeout=50000

该命令会将 Vitest 测试框架中测试的超时值设置为 50 秒,可以根据测试要求将此值替换为不同的时间值。


从 Jest 迁移到 Vitest

将应用的测试从 Jest 迁移到 itest 非常简单。两个测试框架使用类似的API,因此在迁移到 Vitest 时,可能不需要对现有的代码进行重大更改。下面就来看看如何从 Jest 迁移到 Vitest。


首先,我们需要从项目中删除 Jest,并通过运行以下命令安装 Vitest 以及所有必要的依赖项:

npm uninstall jest --save-dev
npm install vitest --save-dev
npm install --save-dev @vue/test-utils

接下来,我们需要在package.json文件中更新测试脚本,以使用Vitest而不是Jest。可以通过将测试脚本更改为Vitest来实现:

"scripts": {
  "test": "vitest",
}

现在,运行以下命令来测试应用:

npm run test

如果在 Jest 测试代码中使用了模块模拟,需要将其更新为以下 Vitest 测试代码:

// Jest
jest.mock('./module-path', () => 'hello')

// Vitest
vi.mock('./module-path', () => ({
  default: 'hello'
})

Vite

网站开发

小程序开发

阅读排行

  • 1. 几行代码就能实现Html大转盘抽奖

    大转盘抽奖是网络互动营销的一种常见形式,其通过简单易懂的界面设计,让用户在游戏中体验到乐趣,同时也能增加商家与用户之间的互动。本文将详细介绍如何使用HTML,CSS和JavaScript来实现大转盘抽奖的功能。

    查看详情
  • 2. 浙江省同区域公司地址变更详细流程

    提前准备好所有需要的资料,包含:房屋租赁合同、房产证、营业执照正副本、代理人身份证正反面、承诺书(由于我们公司其中一区域已有注册另外一公司,所以必须需要承诺书)

    查看详情
  • 3. 微信支付商户申请接入流程

    微信支付,是微信向有出售物品/提供服务需求的商家提供推广销售、支付收款、经营分析的整套解决方案,包括多种支付方式,如JSAPI支付、小程序支付、APP支付H5支付等支付方式接入。

    查看详情
  • 4. 阿里云域名ICP网络备案流程

    根据《互联网信息服务管理办法》以及《非经营性互联网信息服务备案管理办法》,国家对非经营性互联网信息服务实行备案制度,对经营性互联网信息服务实行许可制度。

    查看详情
  • 5. 微信小程序申请注册流程

    微信小程序注册流程与微信公众号较为相似,同时微信小程序支持通过已认证的微信公众号进行注册申请,无需进行单独认证即可使用,同一个已认证微信公众号可同时绑定注册多个小程序。

    查看详情