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

ops/2024/11/19 10:40:39/

一、单元测试

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/ops/134942.html

相关文章

打造专业问答社区:Windows部署Apache Answer结合cpolar实现公网访问

文章目录 前言1. 本地安装Docker2. 本地部署Apache Answer2.1 设置语言选择简体中文2.2 配置数据库2.3 创建配置文件2.4 填写基本信息 3. 如何使用Apache Answer3.1 后台管理3.2 提问与回答3.3 查看主页回答情况 4. 公网远程访问本地 Apache Answer4.1 内网穿透工具安装4.2 创建…

2022数学分析【南昌大学】

2022 数学分析 利用极限定义证明: lim ⁡ n → ∞ 4 n 3 + n − 2 2 n 3 − 10 = 2 \mathop {\lim }\limits_{n \to \infty } \frac{{4{n^3} + n - 2}}{{2{n^3} - 10}} = 2 n→∞lim​2n3−104n3+n−2​=2 ∀ ε > 0 \forall \varepsilon>0 ∀ε>0 要使不等式成立,…

Vue模块化开发的理解

Vue模块化是指在Vue.js开发中&#xff0c;将代码按功能拆分成多个独立的模块&#xff0c;以提高代码的可维护性、可读性和复用性。以下是对Vue模块化的详细理解&#xff1a; 一、Vue模块化的实现方式 组件化开发&#xff1a; Vue组件是模块化的基本单元&#xff0c;每个组件封…

江浙沪智慧城市行业盛会 | 2025杭州国际智慧城市展览会

智慧城市的概念逐渐深入人心&#xff0c;成为现代城市发展的重要方向。杭州&#xff0c;这座历史悠久而又充满活力的城市&#xff0c;正以其独特的魅力吸引着全球的目光。即将到来的2025年&#xff0c;杭州又将迎来一场盛大的智慧城市行业盛会——2025杭州国际智慧城市展览会。…

循环矩阵和BCCB矩阵与向量乘积的快速计算——矩阵向量乘积与频域乘积之间的转换

目录 循环矩阵循环矩阵的定义特征值与特征向量循环矩阵的对角化 循环矩阵与向量的乘积 BCCB矩阵BCCB矩阵的定义BCCB矩阵的对角化BCCB 矩阵与向量的乘积BCCB 矩阵与向量乘积的实现 总结 循环矩阵&#xff08;Circulant Matrix&#xff09;和块循环对称矩阵&#xff08;Block Cir…

【conda】老conda就地更新方法

老conda默认使用经典求解器&#xff0c;比较慢。 手动装包有可能装不上&#xff0c;因为权限问题 可以用conda update conda 来进行更新 更新 conda conda activate base conda update conda就行了 使用 libmamba 求解器 conda config --set solver libmamba

【爬虫实战】抓取某站评论

【爬虫实战】抓取某站评论 声明&#xff1a;本文中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 方式一&#xff1a;JS逆向request发…

【漏洞复现】某全新H5购物商城系统存在前台任意文件上传漏洞(RCE)

漏洞描述 该源码采用HTML5技术开发,可以完美适配各种移动设备,以及iOS和Android系统。同时,易支付接口更为商家提供了便捷的交易功能,让顾客可以轻松通过手机进行网络支付,享受到更加便捷的购物体验。该源码界面设计十分简洁、清爽,同时还保证了购物流程的顺畅和简便。无…