前端项目接入单元测试手册

news/2024/11/19 22:38:43/

一、单元测试

Vue.js项目中的单元测试是一种软件测试方法,通过对最小的、可测试的代码单元进行检查和验证来保证代码质量。确保每个组件作为独立单元正确执行其预定功能。当代码库随着时间发展增长时,单元测试成为识别错误和避免潜在问题的关键手段。此外,编写单元测试能驱动开发者写出更干净、有组织的代码。

二、实现单元测试需掌握以下几点:

1、熟悉Vue Test Utils库;
2、掌握测试运行器Jest的使用;
3、理解掌握测试覆盖率的重要性;

测试覆盖率是衡量测试完整性的一个重要指标,指示了代码被测试所覆盖的程度。完整的测试覆盖率能够让开发者放心地更改和重构代码。在Vue项目中,可以通过配置Jest的collectCoverage选项来生成覆盖率报告。高测试覆盖率有助于确保应用的稳定性,同时也是评估测试效果的一种方式。

4、学会模拟依赖和API调用;

单元测试中,模拟外部依赖和API调用是不可或缺的一部分。模拟可以帮助我们创建一个可控的测试环境,确保组件的单元测试不会受到外部环境的影响。在Vue项目中,开发者可以使用Jest的mock功能来模拟依赖,包括模块、函数甚至是整个库。通过Jest的axios-mock-adapter插件,可以轻松模拟HTTP请求,从而测试组件对API调用的响应。

5、前端单元测试常会用到的几点:

组件渲染:测试组件是否正确渲染,包括检查模板中的元素、属性和内容。确保组件在不同属性和状态组合下都能正确显示。
事件处理:测试组件事件触发器的行为,包括点击、输入、鼠标悬停等。验证事件处理器中的函数是否被正确调用,并检查事件传递的参数。
数据和方法:测试组件的数据和方法,确保它们按预期工作。验证计算属性和侦听器是否根据依赖项的变化而更新。
Props验证:验证组件接受的props类型、必要性和默认值是否符合预期。确保传递无效props时组件能够正确处理或给出警告。
插槽内容:如果组件使用了插槽,测试插槽内容的渲染和行为。确保插槽内容能够正确接收和显示传递给它的数据。
边界条件和异常情况:测试组件在边界条件和异常情况下的表现,如空值、未定义变量或错误的数据类型。确保组件能够优雅地处理这些情况,而不是崩溃或产生不可预测的行为。
性能优化:对于性能敏感的部分,可以编写单元测试来确保代码优化得当。例如,测试组件的渲染速度、内存使用情况或是否避免了不必要的重渲染。
6、在编写单元测试时,建议遵循以下原则:

保持测试简洁:每个测试用例应专注于一个具体的功能点或行为。
使用描述性名称:为测试用例和测试函数使用描述性名称,以便于理解测试的目的和预期结果。
避免冗余测试:不要重复测试已经在其他测试用例中验证过的功能。
模拟外部依赖:对于涉及外部API调用或复杂依赖的组件,使用模拟数据或模拟函数来简化测试环境。
通过关注上述方面并遵循相关原则,可以有效地为Vue 2前端项目编写单元测试,提高代码质量和可维护性。

三、工具介绍

@vue/test-utils:这是Vue官方提供的用于组件单元测试的工具库。关键是能够在隔离的环境下测试组件的行为,而无需担心与其他组件或状态的交互。Vue Test Utils为Vue项目中的单元测试提供了一系列有用的API,它使得测试Vue组件变得简单,能模拟用户交互,如点击、输入并断言组件行为。使用Vue Test Utils进行单元测试意味着可测试组件模板、脚本和样式,从而确保每个组件按预期工作,并能稳健处理边界情况。版本2文档 @vue/test-utils 版本1文档 @vue/test-utils
Jest:jest是facebook推出的一款测试框架,集成了前面所讲的Mocha和chai,jsdom,sinon等功能,是一个令人愉悦的JavaScript测试框架,具有易于上手、快速反馈的特点,特别适用于大型项目。Jest的自动化测试能够极大提高开发效率并减少手动测试的工作。它自带测试覆盖率报告、模拟对象和定时器,支持快照测试。在Vue项目中,Jest可以与Vue Test Utils协同工作,提供一整套解决方案来执行单元测试。快速开始 · Jest

四、安装与配置

1、浏览器环境

npm install --save-dev jsdom jsdom-global

2、单元测试插件
需要接入的插件有jest、@vue/test-utils@^1.*

npm install --save-dev jest @vue/test-utils@^1.3.6

3、配置单元测试脚本
然后我们需要在 package.json 中定义一个单元测试的脚本。

// package.json
{"scripts": {"test": "jest"}
}

4、安装和配置 vue-jest 预处理器
为了告诉 Jest 如何处理 *.vue 文件,我们需要安装和配置 vue-jest 预处理器:

npm install --save-dev vue-jest

接下来在 package.json 中创建一个 jest 块:

{// ..."jest": {"moduleFileExtensions": ["js","json",// 告诉 Jest 处理 `*.vue` 文件"vue"],"transform": {// 用 `vue-jest` 处理 `*.vue` 文件".*\\.(vue)$": "vue-jest"}}
}

5.为 Jest 配置 Babel
尽管最新版本的 Node 已经支持绝大多数的 ES2015 特性,你可能仍然想要在你的测试中使用 ES modules 语法和 stage-x 的特性。为此我们需要安装 babel-jest:

npm install --save-dev babel-jest babel-core@^7.0.0-bridge.0 @babel/core

接下来,我们需要在 package.json 的 jest.transform 里添加一个入口,来告诉 Jest 用 babel-jest 处理 JavaScript 测试文件:

{// ..."jest": {// ..."transform": {// ...// 用 `babel-jest` 处理 js"^.+\\.js$": "<rootDir>/node_modules/babel-jest"}// ...}
}

.babelrc 配置:

{"env": {"test": {"presets": [["env", { "targets": { "node": "current" } }]]}}
}

6、配置Jest支持TypeScript
需要在 Jest 中设置编译 TypeScript。需安装 ts-jest:

 npm install --save-dev ts-jest @types/jest

然后在 package.json 中设置使用 ts-jest 处理 TypeScript 测试文件:

// package.json
{// ..."jest": {"moduleFileExtensions": ["js","ts","tsx","vue"],"transform": {"^.+\.js$": "<rootDir>/node_modules/babel-jest","^.+\.tsx?$": "ts-jest",".*\.(vue)$": "vue-jest"}}
}

最后在tsconfig.json文件中声明jest

// tsconfig.json
{"compilerOptions": {//..."types": ["jest"]}
}

7.放置测试文件
默认情况下,Jest 将会递归的找到整个工程里所有 .spec.js 或 .test.js 扩展名的文件。如果这不符合你的需求,你也可以在 package.json 里的配置段落中改变它的 testRegex

{// ..."jest": {// ..."testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",// ...}
}

8.测试覆盖率
Jest 可以被用来生成多种格式的测试覆盖率报告。以下是一个简单的起步的例子:

扩展你的 jest 配置 (通常在 package.json 或 jest.config.js 中) 的 collectCoverage 选项,然后添加 collectCoverageFrom 数组来定义需要收集测试覆盖率信息的文件。

{"jest": {// ..."collectCoverage": true,"collectCoverageFrom": ["**/*.{js,vue}", "!**/node_modules/**"]}
}

这样就会开启默认格式的测试覆盖率报告。你可以通过 coverageReporters 选项来定制它们。

{"jest": {// ..."coverageReporters": ["html", "text-summary"]}
}

测试覆盖率参数:
Stmts 语句覆盖率
Branch 分支覆盖率
Funcs 函数覆盖率
Lines 行覆盖率

更多文档内容请移步至 Jest 配置文档,在那里你可以找到覆盖率阀值、目标输出目录等选项。

9.测试规范示例

import { mount } from '@vue/test-utils'
import Component from './component'describe('Component', () => {test('is a Vue instance', () => {const wrapper = mount(Component)expect(wrapper.isVueInstance()).toBeTruthy()})
})

10.运行测试命令脚本

npm run test

11.其他
处理webpack别名
如果在 webpack 中配置了别名解析,比如把 @ 设置为 /src 的别名,在jest中也需要用 moduleNameMapper 选项配置

{// ..."jest": {// ...// 支持源代码中相同的 `@` -> `src` 别名"moduleNameMapper": {"^@/(.*)$": "<rootDir>/src/$1","@types": "<rootDir>/src/types/index"}}
}

当前我用的包版本

"vue": "2.7.14",
"@babel/preset-typescript": "^7.26.0",
"@types/jest": "^28.1.8",
"babel-preset-next": "^1.4.0",
"ts-jest": "^29.2.5",
"typescript": "~3.9.3",

推荐jest相关配置包版本

"@vue/test-utils": "^1.3.6",
"jest": "^29.7.0",
"jest-sonar-reporter": "^2.0.0",
"jest-environment-jsdom": "^29.7.0",
"vue-jest": "^3.0.7",
"babel-jest": "^29.7.0",
"vue-template-compiler": "2.7.14", // 与vue版本对应
"babel-core": "^7.0.0-bridge.0",
"identity-obj-proxy": "^3.0.0",

问题梳理

1.jest 不支持解析scss,以下方案行不通。把scss变量不导出的方式解决
https://stackoverflow.com/questions/60841440/syntaxerror-for-scss-in-vue-jest
https://github.com/vuejs/vue-test-utils-jest-example/issues/11
https://github.com/routablehq/jest-scss-transform

参考示例

在UniApp中使用Vue Test Utils和Jest进行单元测试-百度开发者中心
记录使用vue-test-utils + jest 在uniapp中进行单元测试_uniapp 单元测试-CSDN博客
趣谈 Jest 配置

总结与展望

1.接入环境:vue2项目、乾坤框架下vue2项目
2.项目资源:element-ui、yxt-ui 资源引入
3.jest 不支持 scss 资源,如何处理
4.jest 语法有学习成本


http://www.ppmy.cn/news/1548341.html

相关文章

Opengl光照测试

代码 #include "Model.h" #include "shader_m.h" #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" //以上是放在同目录的头文件#include <glad/glad.h> #include <GLFW/glfw3.…

Java项目实战II基于Java+Spring Boot+MySQL的共享汽车管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在共享经济…

11.14 机器学习-朴素贝叶斯+决策树算法

# 贝叶斯底层逻辑 一个数据有可能是几种 结果 选一个概率最高的结果赋给它 # 朴素贝叶斯 假设各个特征之间全部独立 P(A*B*C*D*E)P(A)*P(B)*P(C)*P(D)*P(E) # A是特征向量 B是结果 # P(B|A)P(A|B)*P(B)/P(A) # P(A|X1,X2,X3,X4,X5)P(X1,X2,X3,X4,X5|A)*P(A)/P(X1,X2,X3,X4,X5…

ue5入门教程:EventGraph

EventGraph&#xff08;事件图表&#xff09;是Unreal Engine 5&#xff08;UE5&#xff09;中蓝图系统的一个重要组成部分&#xff0c;它用于展示不同节点和它们之间的事件流。以下是关于UE5中EventGraph的详细教程&#xff1a; 一、EventGraph基础概念 事件&#xff08;Eve…

leetcode_二叉树最大深度

对二叉树的理解 对递归调用的理解 对内存分配的理解 基础数据结构&#xff08;C版本&#xff09; - 飞书云文档 每次函数的调用 都会进行一次新的栈内存分配 所以lmax和rmax的值不会混在一起 /*** Definition for a binary tree node.* struct TreeNode {* int val;* …

ubuntu 22.04 shell

原因&#xff1a;在ubuntu&#xff08;18.04&#xff09;默认是指向bin/dash解释器的&#xff0c;dash是小巧的shell&#xff08;阉割版的bash&#xff09;&#xff0c;其功能远没有bash强大和丰富。上述问题就是dash不支持let和i运算等功能造成的。 ls -la /bin/sh lrwxrwxrw…

【青牛科技】D54123 漏电保护电路介绍及应用

1、具体应用&#xff1a; 相关产品介绍&#xff1a; D54123 应用框图&#xff1a; D54123 方案介绍&#xff1a; 当正常电源电流流过时&#xff0c;电容滤波至少保证 VS端电压为12V R1、R2可根据所用电网交流电压值来选择 C4 应大于 1μF&#xff0c;C2小于 1μF 必须接入 RP&…

Android OpenGLES2.0开发(八):Camera预览

严以律己&#xff0c;宽以待人 引言 终于到该章节了&#xff0c;还记得Android OpenGLES2.0开发&#xff08;一&#xff09;&#xff1a;艰难的开始章节说的吗&#xff1f;写这个系列的初衷就是因为每次用到GLSurfaceViewCamera预览时&#xff0c;总是CtrlC、CtrlV从来没有研究…