Vitest 单元测试

2024-01-12 06:52
文章标签 单元测试 vitest

本文主要是介绍Vitest 单元测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、自动化测试(TDD)的一些概念:

自动化测试(TDD)概念:

自动化测试是指 使用独立于待测软件的其他软件或程序来自动执行测试,比较实际结果与预期 并生成测试报告这一过程。在测试流程已经确定后,测试自动化可以自动执行的一些重复性但必要的测试工作。也可以完成手动测试几乎不可能完成的测试。

自动化测试分类:

1. 基于图形用户交互界面测试

基于用户界面(GUI)的测试使用能够产生图形用户界面操作(如出表点击、键盘输入等)的测试框架,模拟用户动作来以观察、验证程序是否正确的响应。

2. 接口测试

接口测试指的是通过调用接口(API)绕过GUI层,以 API 应用验证行为进行测试。通常API 绕过测试的应用程序的用户界面。它也可以测试 公共(通常)的接口 ,用各种各样的输入参数来验证返回的结果是正确的。

自动化测试有什么意义

1、单元测试的用例可以在代码编写完成之前就设计好,并作为功能的一种定义形式存在。随着新的代码不断完成编写,单元测试随之进行,缺陷被不断找出,因而代码也不断得到改进。

2、手工完成一些软件测试的工作(例如大量的低级接口的回归测试)十分艰苦耗时, 而且寻找某些种类的缺陷时效率并不高,因而测试自动化,提供一种完成这类工作的有效方法。

3、一旦自动化测试方法开发完成,日后的测试工作将可以高效循环完成。很多时候这是针对软件产品进行长期回归测试的高效方法。毕竟早期一个微小的补丁中引入的回归问题可能在日后导致巨大的损失。

前端自动化测试(基于图形用户交互界面测试GUI)有哪些:

1. 单元测试

把代码看成一个个组件,对每个组件进行单独测试,组件内每一个函数的返回结果(或者dom的结构)是不是和期望值一样。

2. e2e(端到端)测试

把程序当做黑盒子,以用户的视角对真实系统的访问行为进行仿真,对测试的输入(用户行为/模拟数据),看能否得到预期得到的结果。

二、Vitest

1、什么是Vitest

vitest是由vite提供支持的下一代测试框架

该工具一开始就考虑到了vite,利用了在DX中的改进,例如即时热模块重新加载(HMR)

2、vite的目标

定位为vite项目的首选测试运行者,甚至对于不使用vite的项目来说也是一个可靠的替代方案

3、vitest和其他测试框架的比较

3.1 Jest vs Vitest

Jest

  • 接管了测试框架领域,jest团队和社区创建了很多测试API,并推动了许多测试模式,这些模式已经成为了web生态系统的标准

Vitest

  • 你的项目没有使用vite:提供大多数与jest的api和生态系统的兼容性,可以让你更快地运行单元测试,在大多数项目中,是Jest的直接替代品
  • 你的项目使用vite:如果使用Jest,那么需要配置和维护两个不同的管道,这是不合理的,如果使用vitest,那么您可以将开发,构建,测试环境的配置定义为单个管道,共享相同的插件和相同的vite.config.js,避免了重复性的麻烦

3.2、Cypress vs Vitest

cypress 定义

被称为端到端测试工具,其新组件测试运行期对测试vite有很大的支持,并且·是测试浏览器中呈现的内容的理想选择
 
是基于浏览器的测试运行期,是vite的补充工具,将捕获vitest无法捕获的问题(因为其使用真实的浏览器和真实的浏览器api)

vitest定义

是基于节点的运行程序,专注于为闪电般的无头测试提供最佳DX,

cypress 功能

用于e2e和组件测试


其测试驱动恒旭专注于确定元素是否可见,可访问,交互,cypress专为UI开发和测试而构建,测试完成之后,您可以使用浏览器开发工具调试发生的任何故障
 
像IDE,您可以在浏览器中看到真实渲染的组件以及测试结果和日志


vitest 功能

用于单元测试(测试无头代码的好选择)
 
支持各种部分实现的浏览器环境,例如Jsdom,这些环境足以让您快速对引用浏览器api的任何代码进行单元测试,代价是这些浏览器环境在其可实现的功能方面存在限制,例如jsdom缺少很多功能(window.navigation,布局引擎offsetTop)
使用

对应用程序中的所有无头逻辑使用vitest,对所有基于浏览器的逻辑使用cypress
 

4、vitest配置

安装:

pnpm install -D vitest

package.json配置

 "test:unit": "vitest --typecheck",

 运行模式,运行或者监听

vitest watch      监听模式 为执行vitest的默认模式

vitest run   运行模式

可以直接在当前的vite.config.ts文件中配置

/// <reference types="vitest" />

...

  test: {

    globals:true, // 是否全局引入

    environment:"happy-dom" // 环境选择 jsdom

    // include: ['test/**/*.test.ts'],

    // deps: {

    //   inline: ['@vue', '@vueuse', 'element-plus', 'vue-i18n'],

    // },

  },

也可以单独创建一个vitest.config.ts文件,优先级高于vite.config.ts

import { fileURLToPath } from 'node:url'
import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
import viteConfig from './vite.config'
export default mergeConfig(viteConfig,defineConfig({define: {'import.meta.vitest': 'undefined', // 源码内联测试配置}, test: {// 启用基准测试模式  mode: 'benchmark',  // globals: true, // 全局引入vitest 位置一environment: 'jsdom',exclude: [...configDefaults.exclude, 'e2e/*'],includeSource: ['src/**/*.{js,ts}'], root: fileURLToPath(new URL('./', import.meta.url)),coverage: {provider: 'istanbul', // or 'v8'  默认使用v8reporter: ['text', 'html', 'json'],// reporters: ['verbose'],reporters: ['html'],// reportsDirectory: './tests/unit/coverage', // 修改输出报告位置exclude:['src/**/icons'] //不需要单元测试覆盖的地方},// browser: {//   enabled: true,//   name: 'chrome', // browser name is required// },}})
)

6、测试可过滤

当只需要运行某个测试文件,或者包含某字符串的测试文件

$ vitest basic

将只执行包含 basic 的测试文件,例如:

basic.test.ts
basic-foo.test.ts
basic/foo.test.ts

7、 .concurrent、.sequential

如果在测试套件中使用 .concurrent,则其中的每个测试用例都将并发运行。

你还可以将 .skip(跳过).only (仅执行这个)和 .todo (待完成)用于并发测试套件和测试用例。

sequential  按顺序测试

fails 明确表示断言失败

运行并发测试时,快照和断言必须使用本地测试上下文中的 expect,以确保检测到正确的测试。

test.concurrent("test 1", async ({ expect }) => {
  expect(foo).toMatchSnapshot();
});
test.concurrent("test 2", async ({ expect }) => {
  expect(foo).toMatchSnapshot();
}); 

8、快照

当希望确保函数的输出不会意外更改时,可以使用快照测试,兼容 Jest 快照测试。使用快照时,Vitest 将获取给定值的快照,将其比较时将参考存储在测试旁边的快照文件。如果两个快照不匹配,则测试将失败:要么更改是意外的,要么参考快照需要更新到测试结果的新版本。

// 此测试在第一次运行时,Vitest 会创建一个快照文件

expect(result).toMatchSnapshot()

// 内联快照  这允许你直接查看期望输出,而无需跨不同的文件跳转。expect(result).toMatchInlineSnapshot(`"FOOBAR"`)

// 文件快照会以文件的方式存储  

await expect(result).toMatchFileSnapshot('../__snapshots__/HelloWorld1.json') // 文件保存路径

自动更新内联快照内容:

 npx vitest -u

执行 npm run vitest 命令 不会更新内联快照

9、对象模拟(Mocking)

10、测试覆盖率

 npx vitest --coverage 输出覆盖范围

Vitest 通过 v8(默认) 支持原生代码覆盖率,通过 istanbul 支持检测代码覆盖率。

// vitest.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      provider: 'istanbul', // or 'v8'
    },
  },
})

定义输出报告的格式

// vitest.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      reporter: ['text', 'json', 'html'],
    },
  },
})

这个属性定义了覆盖率报告的输出格式。这里指定了三种格式:文本、JSON 和 HTML。这意味着在运行测试时,Vitest 将生成并输出这三种格式的覆盖率报告。

11、源码内联测试

// src/index.ts

// 函数实现
export function add(...args: number[]) {
  return args.reduce((a, b) => a + b, 0)
}

// 源码内的测试套件
if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest
  it('add', () => {
    expect(add()).toBe(0)
    expect(add(1)).toBe(1)
    expect(add(1, 2, 3)).toBe(6)
  })
}

更新配置文件

// vite.config.ts
/// <reference types="vitest" />
import { defineConfig } from 'vite'

export default defineConfig({

 define: {

    'import.meta.vitest': 'undefined', // 源码内联测试配置

  },

  test: {
    includeSource: ['src/**/*.{js,ts}'], 
  },
})

12、ts类型测试

import { assertType, expectTypeOf ,test} from 'vitest'
import { mount } from '../../assets/common'test('my types work properly', () => {expectTypeOf(mount).toBeFunction()expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>() //  验证 mount 函数的第一个参数的类型是否为 { name: string }。// @ts-expect-error name is a string       // 这是一个注释,指示 TypeScript 在编译时应该期望一个错误,因为接下来的代码会尝试将一个非字符串值赋给 name。assertType(mount({ name: 42 })) // 尝试调用 mount 函数并传递一个对象作为参数,其中 name 的值是 42(一个数字,而不是字符串)。由于前面的注释,TypeScript 应该期望这里有一个类型错误。
})

说明​

此功能可用于:

  • 小范围的功能或 utils 工具的单元测试
  • 原型设计
  • 内联断言

对于更复杂的测试,比如组件测试或 E2E 测试,建议使用单独的测试文件取而代之

vitest 退出及时更新模式

npx vitest run

要重新打开Vitest的多线程功能,您需要移除--no-threads选项,然后再次运行测试。

例如,如果您之前使用以下命令禁用了多线程:

vitest --no-threads

要重新打开多线程功能,只需运行以下命令:

vitest

这将重新启用Vitest的多线程功能,并允许测试并行运行以提高执行效率。

请注意,禁用多线程功能可能会降低测试的执行效率,因为测试将按顺序逐个执行,而不是并行运行。在大多数情况下,建议使用多线程功能来提高测试的执行效率。

  1. assert(value, message):断言函数返回的值是否为真。如果断言失败,则抛出错误并显示提供的消息。
  2. toBe(value):断言函数返回的值是否严格等于给定的值。
  3. toBeCloseTo(value, precision):断言函数返回的值是否接近给定的值。precision 参数指定小数点后的位数。
  4. toBeDefined():断言函数返回的值是否已定义(不是 undefined)。
  5. toBeFalsy():断言函数返回的值是否为假值(false、null、undefined、0、NaN 或空字符串)。
  6. toBeGreaterThan(value):断言函数返回的值是否大于给定的值。
  7. toBeLessThan(value):断言函数返回的值是否小于给定的值。
  8. toBeNaN():断言函数返回的值是否为 NaN。
  9. toBeNull():断言函数返回的值是否为 null。
  10. toBeTruthy():断言函数返回的值是否为真值(true、非空对象、非零数字、非 NaN)。
  11. toBeUndefined():断言函数返回的值是否未定义(undefined)。
  12. toContain(element):断言函数返回的数组是否包含指定的元素。
  13. toEqual(value):断言函数返回的值是否与给定的值相等。
  14. toMatch(pattern):断言函数返回的值是否匹配正则表达式或字符串。

1、两种单元测试文件名.spec.ts文件和.test.ts的区别:

  • .spec.ts文件和.test.ts文件在软件开发中都用于编写测试代码,但它们之间存在一些关键的区别。
  • 首先,规范(spec)文件通常用于描述和验证行为,特别是在软件开发中。在Angular开发中,规范文件是用于编写单元测试和集成测试的脚本文件。这些文件扩展名为“spec.ts”,并且在Angular开发中,每个.ts文件都应对应一个.spec.ts文件。它们通过Karma测试运行程序(使用Jasmine JavaScript测试框架)来运行测试。
  • 另一方面,test.ts文件通常用于编写任何类型的测试代码,包括单元测试、集成测试等。这些文件扩展名为.ts,并且它们没有特定的命名约定或用途。它们可以用于任何需要测试的场合,包括但不限于软件开发。
  • 总的来说,.spec.ts文件和.test.ts文件之间的主要区别在于它们的用途和上下文。规范文件主要用于描述和验证行为,特别是在软件开发中,而test.ts文件则用于任何需要测试的场合,没有特定的用途或目标。

compose函数

const add1 = (x) => x + 1;
const mul3 = (x) => x * 3;
const div2 = (x) => x / 2;

function compose(...funcs){
    return function anonymous(val){debugger;
        if(funcs.length===0) return val;
        if(funcs.length===1) return funcs[0](val);
        return funcs.reverse().reduce((N,item)=>{
              return item(N)
        },val)
    }
}

compose(add1,mul3,div2)(3)

这篇关于Vitest 单元测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/597112

相关文章

springboot+maven搭建的项目,集成单元测试

springboot+maven搭建的项目,集成单元测试 1.在pom.xml文件中引入单元测试的依赖包 <!--单元测试依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></depen

PowerMock 单元测试总结与常见坑解决方案

PowerMock 单元测试总结与常见坑解决方案 官方文档: PowerMock GitHub PowerMock 在单元测试中能够帮助我们解决静态类、final 方法、私有方法等无法轻易 mock 的问题。下面是我在实际使用 PowerMock 时踩过的一些坑,并结合 PowerMock 的一些方法进行总结。 基本依赖和设置 在 Maven 中添加 PowerMock 依赖。在测试

JAVA—单元测试

单元测试:就是针对最小的功能单元(方法),编写测试代码对其进行正确性测试     之前是使用main函数调用来进行检测,无法实现自动化测试 也会影响其他方法的测试 目录 1.junit框架概述 2.junit框架的常见注解 1.junit框架概述 package High_junit;//字符串工具类 用于测试public class String_ju

idea单元测试报错找不到主类

报错截图 主要是单测中没有配置类 在下面的command line 中选择jar manifest 因为条参数过长,这里设置只使用主类 详细解释见: https://www.jianshu.com/p/8322b3b17040

file | 某文件夹【解耦合】下的文件查找功能实现及功能单元测试

文件查找工具 概要思路OS模块 --- 学习版os.getcwd()os.path.dirname(os.getcwd())os.path.dirname() 和 os.path.basename() OS模块 — 实战版单元测试解耦合 概要 梳理业务主逻辑: 查看存放被采集JSON数据的文件夹内的文件列表【所有 包含文件夹下的文件夹下的文件】 这是本节内容聚焦的点和My

【JUnit单元测试框架】

单元测试的概念 单元测试,顾名思义,是针对软件中的最小可测试部分(通常是类或方法)进行的测试。它的目的是确保这些最小单元按照预期工作,从而帮助开发者快速定位和解决问题。单元测试通常遵循“隔离”原则,即测试一个功能单元时,应该尽量减少对其他部分的依赖,以便专注于当前单元的行为。 历史做法及其问题 将所有测试代码都放在main方法中,并通过main方法去调用其他方法进行测试。这种做法存在几个显著

visual studio2015单元测试

尝试引用了包含待测了待测程序的项目,但是不知道该如何调用待测代码,所以只能通过引用生成的库文件 进行单元测试的步骤: 一、创建控制台静态库项目,将要测试的代码编译为库文件 二、创建单元测试项目,引用创建的库文件,并在stdafx.h中包含之前库文件的头文件: 1)直接include头文件的绝对路径 2)将头文件复制到单元测试项目的根目录下,并直接在stdafx.h头文件中include头

软件测试常用工具总结(测试管理、单元测试、接口测试、自动化测试、性能测试、负载测试...)

前言 在软件测试的过程中,多多少少都是会接触到一些测试工具,作为辅助测试用的,以提高测试工作的效率,使用好了测试工具,能对测试起到一个很好的作用,同时,有些公司,也会要求掌握一些测试工具,或者,是在面试时,也会被问到测试工具的,比如,在面试时,最常见的问题便是,你在测试时,用的是什么测试工具?或者,要做性能测试时,要用什么测试工具进行测试会比较好?等等问题。 作为测试人员,了解下现在有哪些

单元测试 Mock不Mock?

文章目录 前言单元测试没必要?Mock不Mock?什么是Mock?Mock的意义何在? 如何Mock?应该Mock什么?Mock 编写示例 总结 前言 前段时间,我们团队就单元测试是否采用 Mock 进行了一番交流,各有各的说法。本文就单元测试 Mock不Mock 给出我的观点,欢迎各位同仁提出不同的意见,共同探讨、相互交流。 单元测试没必要? 我见过好多不写单元测试的项目,

RD单元测试和QA接口测试的区别

1.单元测试 单元测试的基本原则:单元测试应该测试独立的单元模块,这个单元不应依赖于其他模块。 单元测试会强迫你去把各个模块解耦,因为耦合的很紧的模块是很难进行单元测试的,一般情况下,一个普通的程序员在任务很紧的时候很难费劲心思去将代码进行模块化的;当为了单元测试,自己就会去想方设法将模块解耦,这也算是单元测试的一个副产品吧。 单元测试能够进行最仔细的最细致的最方便的最全面的测试;只要测试用