Vue 组件的单元测试
1、基本的示例
单元测试是软件开发非常基础的一部分。单元测试会封闭执行最小化单元的代码,使得添加新功能和追踪问题更容易。Vue 的单文件组件使得为组件撰写隔离的单元测试这件事更加直接。它会让你更有信心地开发新特性而不破坏现有的实现,并帮助其他开发者理解你的组件的作用。
这是一个判断一些文本是否被渲染的简单的示例:
<template><div><input v-model="username"><divv-if="error"class="error">{{ error }}</div></div>
</template>
<script>
export default {name: 'Hello',data () {return {username: ''}},computed: {error () {return this.username.trim().length < 7? 'Please enter a longer username': ''}}
}
</script>
import { shallowMount } from '@vue/test-utils'
import Hello from './Hello.vue'
test('Hello', () => {// 渲染这个组件const wrapper = shallowMount(Hello)// `username` 在除去头尾空格之后不应该少于 7 个字符wrapper.setData({ username: ' '.repeat(7) })// 确认错误信息被渲染了expect(wrapper.find('.error').exists()).toBe(true)// 将名字更新至足够长wrapper.setData({ username: 'Lachlan' })// 断言错误信息不再显示了expect(wrapper.find('.error').exists()).toBe(false)
})
上述代码片段展示了如何基于 username 的长度测试一个错误信息是否被渲染。它展示了 Vue 组件单元测试的一般思路:渲染这个组件,然后断言这些标签是否匹配组件的状态。
2、为什么要测试?
组件的单元测试有很多好处:
- 提供描述组件行为的文档
- 节省手动测试的时间
- 减少研发新特性时产生的 bug
- 改进设计
- 促进重构自动化测试使得大团队中的开发者可以维护复杂的基础代码
3、实际的例子
单元测试应该:
- 可以快速运行
- 易于理解
- 只测试一个独立单元的工作我们在上一个示例的基础上继续构建,同时引入一个工厂函数 (factory function)使得我们的测试更简洁更易读。这个组件应该:
- 展示一个“Welcome to the Vue.js cookbook”的问候语
- 提示用户输入用户名
- 如果输入的用户名少于七个字符则展示错误信息让我们先看一下组件代码:
<template><div><div class="message">{{ message }}</div>Enter your username: <input v-model="username"><divv-if="error"class="error">Please enter a username with at least seven letters.</div></div>
</template>
<script>
export default {name: 'Foo',data () {return {message: 'Welcome to the Vue.js cookbook',username: ''}},computed: {error () {return this.username.trim().length < 7}}
}
</script>
我们应该测试的内容有:
- message 是否被渲染
- 如果 error 是 true,则 应该展示
- 如果 error 是 false,则 不应该展示我们的第一次测试尝试:
import { shallowMount } from '@vue/test-utils'
import Foo from './Foo.vue'
describe('Foo', () => {it('renders a message and responds correctly to user input', () => {const wrapper = shallowMount(Foo, {data: {message: 'Hello World',username: ''}})// 确认是否渲染了 `message`expect(wrapper.find('.message').text()).toEqual('Hello World')// 断言渲染了错误信息expect(wrapper.find('.error').exists()).toBeTruthy()// 更新 `username` 并断言错误信息不再被渲染wrapper.setData({ username: 'Lachlan' })expect(wrapper.find('.error').exists()).toBeFalsy()})
})
上述代码有一些问题:
- 单个测试断言了不同的事情
- 很难阐述组件可以处于哪些不同的状态,以及它该被渲染成什么样子接下来的示例从这几个方面改善了测试:
- 每个 it 块只做一个断言
- 让测试描述更简短清晰
- 只提供测试需要的最小化数据
- 把重复的逻辑重构到了一个工厂函数中 (创建 wrapper 和设置 username 变量)更新后的测试:
import { shallowMount } from '@vue/test-utils'
import Foo from './Foo'
const factory = (values = {}) => {return shallowMount(Foo, {data () {return {...values}}})
}
describe('Foo', () => {it('renders a welcome message', () => {const wrapper = factory()expect(wrapper.find('.message').text()).toEqual("Welcome to the Vue.js cookbook")})it('renders an error when username is less than 7 characters', () => {const wrapper = factory({ username: '' })expect(wrapper.find('.error').exists()).toBeTruthy()})it('renders an error when username is whitespace', () => {const wrapper = factory({ username: ' '.repeat(7) })expect(wrapper.find('.error').exists()).toBeTruthy()})it('does not render an error when username is 7 characters or more', () => {const wrapper = factory({ username: 'Lachlan' })expect(wrapper.find('.error').exists()).toBeFalsy()})
})
注意事项:
在一开始,工厂函数将 values 对象合并到了 data 并返回了一个新的 wrapper 实例。这样,我们就不需要在每个测试中重复 const wrapper = shallowMount(Foo)。另一个好处是当你想为更复杂的组件在每个测试中伪造或存根一个方法或计算属性时,你只需要声明一次即可。
4、额外的上下文
上述的测试是非常简单的,但是在实际情况下 Vue 组件常常具有其它你想要测试的行为,诸如:
- 调用 API
- 为 Vuex 的 store,commit 或 dispatch 一些 mutation 或 action
- 测试用户交互我们在 Vue Test Utils 的教程中提供了更完整的示例展示这些测试。
Vue Test Utils 及庞大的 JavaScript 生态系统提供了大量的工具促进 100% 的测试覆盖率。单元测试只是整个测试金字塔中的一部分。其它类型的测试还包括 e2e (端到端) 测试、快照比对测试等。单元测试是最小巧也是最简单的测试——它们通过隔离单个组件的每一个部分,来在最小工作单元上进行断言。
快照比对测试会保存你的 Vue 组件的标记,然后比较每次新生成的测试运行结果。如果有些东西改变了,开发者就会得到通知,并决定这个改变是刻意为之 (组件更新时) 还是意外发生的 (组件行为不正确)。
端到端测试致力于确保组件的一系列交互是正确的。它们是更高级别的测试,例如可能会测试用户是否注册、登录以及更新他们的用户名。这种测试运行起来会比单元测试和快照比对测试慢一些。
单元测试中开发的时候是最有用的,即能帮助开发者思考如何设计一个组件或重构一个现有组件。通常每次代码发生变化的时候它们都会被运行。
相关文章:
Vue 组件的单元测试
1、基本的示例 单元测试是软件开发非常基础的一部分。单元测试会封闭执行最小化单元的代码,使得添加新功能和追踪问题更容易。Vue 的单文件组件使得为组件撰写隔离的单元测试这件事更加直接。它会让你更有信心地开发新特性而不破坏现有的实现,并帮助其他…...

海底两万里的思维导图,轻松了解整体的内容
《海底两万里》是一部经典的科幻小说。小说以其丰富的想象力和对海底世界的描绘而闻名于世。今天我们就用思维导图的分支介绍这个作品到底讲了什么。(思维导图示例:迅捷画板) 《海底两万里》是“凡尔纳三部曲”中的第二部(其它两部…...

ZABBIX 6.4官方安装文档
一、官网地址 Zabbix:企业级开源监控解决方案 二、下载 1.选择您Zabbix服务器的平台 2. Install and configure Zabbix for your platform a. Install Zabbix repository # rpm -Uvh https://repo.zabbix.com/zabbix/6.4/rhel/8/x86_64/zabbix-release-6.4-1.el8…...

本地MQTT服务器搭建(EMQX)
一、下载EMQX 下载地址:EMQ (emqx.com) 打开官网后,选择右边的免费试用按钮 然后单击EMQX Enterprise标签,然后选择下面的EMQX开源版,选择开源版的系统平台为Windows,单击免费下载。 在新页面下单击立即下载 二、安装…...
Docker启动pandora并指定ACCESS TOKEN
把chatGPT_ACCESS_TOKEN改成你的ACCESS_TOKEN 《chatGPT ACCESS TOKEN获取地址(需要魔法)》 docker run -d -m 512m -p 88:88 --privilegedtrue -e PANDORA_SERVER0.0.0.0:88 -e PANDORA_ACCESS_TOKENchatGPT_ACCESS_TOKEN --name pandora pengzhile/pa…...

Python + Jmeter 实现自动化性能压测
Step01: Python脚本开发 文件路径:D://wl//testproject//Fone-grpc//project1//test_client.py Python 脚本作用: 通过 grpc 调用底层 c 的接口,做数据库的数据插入与查询操作,然后将返回的结果进行拼接与输出。 2.代码里面将…...

【Linux进行时】进程状态
进程状态: ❓假设我们在上课,在B站上上课,请问我们的B站是不是一直运行呢?💡不是的! ❓假设我们同时打开了B站和PDF阅读器时,是怎么运行的呢? 💡每一个进程在CPU跑一会&a…...

HarmonyOS开发环境搭建
一 鸿蒙简介: 1.1 HarmonyOS是华为自研的一款分布式操作系统,兼容Android,但又区别Android,不仅仅定位于手机系统。更侧重于万物物联和智能终端,目前已更新到4.0版本。 1.2 HarmonyOS软件编程语言是ArkTS,…...

友思特新闻|友思特与IDS深化战略合作伙伴关系
尊敬的客户和合作伙伴, 我们非常高兴地宣布,友思特已经与国际领先的机器视觉解决方案提供商 IDS 深化了我们的合作关系。 作为 IDS 的长期合作伙伴,友思特一直致力于为国内客户提供最先进的机器视觉技术和解决方案。 自从友思特与 IDS 合作…...

ARM Linux DIY(十三)Qt5 移植
前言 板子带有屏幕,那当然要设计一下 GUI,对 Qt5 比较熟悉,那就移植它吧。 移植 Qt5 buildroot 使能 Qt5,这里我们只开启核心功能 gui module --> widgets module 编译 $ make ODIY_V3S/ qt5base编译报错:找不…...

二,手机硬件参数介绍和校验算法
系列文章目录 第一章 安卓aosp源码编译环境搭建 第二章 手机硬件参数介绍和校验算法 第三章 修改安卓aosp代码更改硬件参数 第四章 编译定制rom并刷机实现硬改(一) 第五章 编译定制rom并刷机实现硬改(二) 第六章 不root不magisk不xposed lsposed frida原生修改定位 第七章 安卓…...

ubunutu20/18/22 编译android 5相关的问题汇总-千里马framework开源代码平板编译过程
hi,粉丝朋友们: 闲鱼50块钱淘到了一个开源平板,注意这个平板是有源码的,可以进行相关的编译修改。哈哈哈,马哥这边就体验了一下50块钱平板是否可以拿来做framework呢? 哈哈,说好就开干了&#x…...
tauri vue vite
准备 rust 根据 https://www.rust-lang.org/tools/install,安装 rust 执行 cargo --version 检查安装是否完成nodejs 安装 nodejstauri cargo install create-tauri-app --lockedcargo create-tauri-app 选择: ✔ Project name tauri-app ✔ Choose wh…...
名词解析与经验分享(前端)
目录 1.什么是sass产品 2.下面我想说说事件循环 3. cmd窗口的一些快捷键 4. 组件与插件的区别 5. vue项目嵌入app后调用app方法 6.点击编辑按钮直接回到顶部,输入框光标闪动聚焦 7.短轮询与长轮询 短轮询 长轮询 8.前端moment库 9.移动端-触底刷新实现核心…...
【前端】js下载url文件
不打开新窗口进行下载 function download(res) { var elemIF document.createElement("iframe"); elemIF.src res; elemIF.style.display "none"; document.body.appendChild(elemIF); } window.open(url, _blank); a标签 const ele …...

什么是 BSD 协议?
BSD开源协议是一个给于使用者很大自由的协议。可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。当你发布使用了BSD协议的代码,或者以BSD协议代码为基础做二次开发自己的产品时,需要满足三个条件&…...

【网络教程】揭秘Windows SSH服务端免密登录:告别繁琐,享受安全连接
文章目录 开启Windows下的SSH服务端图形界面安装手动下载安装Windows如何查看系统用户名Windows如何查看本机IP开启免密登录Window生成秘钥Linux下生成秘钥配置公钥视频讲解开启Windows下的SSH服务端 这篇文章演示的环境是Windows11Windows的SSH服务端默认情况下是没有安装的,…...
使用键盘控制Franka机械臂运动
功能说明 使用键盘按键,可以控制franka机械臂7个关节角,已在真机上验证。 代码 主要使用的是官方包内的 franka_example_controllers 1、修改 include下的 joint_position_example_controller.h, 改为如下: // Copyright (c) 2017 Frank…...
力扣第45天----第392题、第115题
# 力扣第45天----第392题、第115题 文章目录 一、第392题--判断子序列二、第115题--不同的子序列 一、第392题–判断子序列 挺简单的,思路跟以前的都差不多。 class Solution { public:bool isSubsequence(string s, string t) {vector<vector<int>&g…...

扔掉你的开发板,跟我玩Mcore-全志h616
本文转载自WhyCan Forum(哇酷开发者社区): https://whycan.com/t_10024.html 作者leefei 这是一个1.69寸触摸小电视。使用全志H616芯片,板上硬件有mpu6050陀螺仪,USB转ttl调试串口,一个USB接口,WIFI&蓝牙&#x…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...