试试前端自动化测试(基础篇)

众所周知的原因,前端作为一种特殊的 GUI 软件,做自动化测试困难重重。在快速迭代,UI 变动大的业务中,自动化测试想要落地更是男上加男 🐶。

近期的学习过程中,翻阅了众多前端自动化测试相关的文章,大多数都在讲如何使用自动化测试框架对前端代码进行测试,很少讲解为什么要引入自动化测试,引入自动化测试有哪些好处,哪些项目适合引入自动化测试,但这些才是真正我们想要知道的。

考虑到各位读者爸爸们可能没有接触过自动化测试的内容,这篇文章就从基本概念和基础用法入手,为大家讲解自动化测试的内容。

开始之前,先进行一下前戏(可能比较长,不喜欢的可以快进 🐶):

情景还原

小王是国内一家大厂的前端开发。就在述职前一周,产品经理给了一个需求,要求在老项目上加上新的功能。

小王打开老项目代码,定睛一看,心头一紧 —— 要改的组件已经长达 800 多行,快速扫一眼,发现还没有注释。 小王哭了,但产品经理要求 3 天内实现新功能,没办法,只能硬着头皮写了。

小王准备开始写了,对新功能大致做了一下技术分析,发现与老代码的耦合比较厉害,于是就开始一边写,一边阅读和修改老代码。

老代码又臭又长,小王发现有一段代码不知道为什么要对输入文本做处理,觉得是一段没有用的代码,还影响到自己添加新功能,于是小王把这段代码删掉了。

新功能按期完成,小王经过了简单的手工自测,没有问题,于是就发送了提测邮件,等待测试反馈,开开心心准备述职去了。

对新功能的测试也顺利通过,小王将新功能发布上线,结束了这周的工作,回家享受周末了。

小王早早地洗漱完上床睡觉了,突然大半夜老板打电话过来:小王,快起来,出 BUG 了,影响了 1w+ 的用户,快起来看看什么问题!

小王猛地起身,从背包里取出电脑,开始排查 BUG 出现的原因,一顿 debug 之后,发现竟然是自己删掉的那段老代码导致了 BUG

小王又一次哭了,修复好 BUG,紧急发布上线。

“下周一就述职了,今天出这么个 BUG,年终奖肯定没了,普调估计也悬。还要写 case 报告抄送大部门,丢人丢到家了。”

但是如果公司的老项目引入了自动化测试,后来的故事就完全不一样了:

情景反转

小王准备开始写了,对新功能大致做了一下技术分析,发现与老代码的耦合比较厉害,于是就开始一边写,一边阅读和修改老代码。

老项目的前端开发为了保证项目能够正常运行,编写了单元测试和集成测试的代码,在 README 里要求维护的同事要在添加/修改了代码之后跑一遍测试用例。

老代码又臭又长,小王发现有一段代码不知道为什么要对输入文本做处理,觉得是一段没有用的代码,还影响到自己添加新功能,于是小王把这段代码删掉了。

小王删掉代码之后跑测试用例,突然好几个刺眼的红色字符映入眼帘 —— FAIL TO TEST

一看测试用例描述,小王这才知道这段代码的作用。于是小王对这段代码做了重构,同时也加上了新功能,跑一遍测试用例 —— 全是绿色的 PASS

小王长舒一口气,给自己的新功能也加上了测试用例,修修改改让新加的测试用例也跑通了。

虽然小王因为编写测试用例稍微加班了一会,但是他感觉一身轻松,非常有安全感。

提测、发布一切正常,小王享受了一个愉快的周末。

下周回来之后述职,心情大好,状态极佳,得到老板们的赞赏。绩效评定棒棒哒,年终奖和普调都没问题。

上面的故事都是我 YY 的,如有雷同纯属巧合 🐶。

什么是测试?

测试其实就是在已经开发完成的软件之上采用人工或非人工的方式验证软件是否符合工程预期,是否会造成用户/开发商损失等潜在问题的一种方式。

大多数情况下,我们编写的前端代码都是开发手工自测,又或是提测后由专门的测试人员手工测试。

手工测试当然也是没有问题的,但是通过自动化的测试工具,可以更加快速高效且准确定位问题所在。

自动化测试实际上是运行一段测试代码,去验证目标代码是否满足某个期望。

本文后续的内容中,“测试”一词将专门指代自动化测试

为什么要测试?

我们进行测试的目的在于,及时发现错误,提高代码质量和开发效率,避免存在 BUG 的代码发布上线造成损失。

测试自动化的好处在于反馈及时,能够极大地提高前端的开发效率。

在我们日常的开发过程中,是不是经常需要在项目跑起来之后去人工测试某些操作或者流程是否能够正常运行?是不是经常需要打断点或者使用 console.log 查看控制台信息来检查某个函数是否执行?

这些需要我们自己手工测试代码的执行结果是否符合预期的场景,完全可以使用自动化测试的脚本代替。

现有的很多成熟的自动化测试框架完全可以模拟我们的手工操作,使用脚本自动运行测试用例,通常只需要几秒就能给出准确的反馈,同时还能侦听代码变化,自动执行项目中发生了变化的代码对应的测试用例,能够极大提高我们的开发效率。

在公司业务和人员变动都比较快的当下,编写自动化测试脚本的收益越来越高。开发者再也不用害怕引入回归 BUG,也再也不用害怕把代码交给他人维护。有了测试脚本的约束,迭代/重构都能更加从容。

测试自动化的收益=迭代次数×全手动执行成本−首次自动化成本−维护次数×维护成本测试自动化的收益 = 迭代次数 \times 全手动执行成本 - 首次自动化成本 - 维护次数 \times 维护成本测试自动化的收益=迭代次数×全手动执行成本−首次自动化成本−维护次数×维护成本

有哪些测试类型?

前端测试主要分为 3 种:单元测试(Unit Test)集成测试(Integration Test)UI 测试(UI Test)

三种测试的占比分别为:

现实是,大多数公司的测试金字塔是倒过来的,由人工进行UI 测试反而是最多的,集成测试单元测试却大多被忽略。

单元测试(Unit Test)

单元测试是最容易实现的:代码中多个组件共用的工具类库、多个组件共用的子组件等。

通常情况下,在公共函数/组件中一定要有单元测试来保证代码能够正常工作。单元测试也应该是项目中数量最多、覆盖率最高的。

能进行单元测试的函数/组件,一定是低耦合的,这也从一定程度上保证了我们的代码质量。

集成测试(Integration Test)

集成测试通常被应用在:耦合度较高的函数/组件、经过二次封装的函数/组件、多个函数/组件组合而成的函数/组件等。

集成测试的目的在于,测试经过单元测试后的各个模块组合在一起是否能正常工作。会对组合之后的代码整体暴露在外接口进行测试,查看组合后的代码工作是否符合预期。

集成测试是安全感较高的测试,能很大程度提升开发者的信心,集成测试用例设计合理且测试都通过能够很大程度保证产品符合预期。

UI 测试(UI Test)

在我学习查阅文献的过程中,我发现国内不少文章都将 UI 测试(UI Test)和端到端测试(E2E Test)混为一谈,认为是同一个测试类型。

事实上,UI 测试(UI Test)和端到端测试(E2E Test)是稍有区别的:

UI 测试(UI Test)只是对于前端的测试,是脱离真实后端环境的,仅仅只是将前端放在真实环境中运行,而后端和数据都应该使用 Mock 的。

端到端测试(E2E Test)则是将整个应用放到真实的环境中运行,包括数据在内也是需要使用真实的。

就前端而言,UI 测试(UI Test)更贴近于我们的开发流程。在前后端分离的开发模式中,前端开发通常会使用到 Mock 的服务器和数据。因而我们需要在开发基本完成后进行相应的 UI 测试(UI Test)。

UI 测试的自动化程度还不高,大多数还依赖于手工测试。

在一些自动化测试工具中有创建快照的功能,也能帮助我们在一定程度上实现 UI 测试(UI Test)的自动化。

哪些项目适合引入自动化测试?

目前市面上的大多数文章都没有讲过这个问题,但事实上这个问题是最值得思考的!

在化学上有一句名言:

抛开剂量谈毒性都是耍流氓。

同理,在前端自动化测试方面,抛开项目类型、软件开发的人员配置和生命周期而谈论自动化测试的好处和必要性,也是耍流氓。

于我个人而言,我比较喜欢写测试代码,当看到测试用例都全部 PASS 都是绿色的时候,非常舒服。

但我猜大部分的开发都会觉得:需求这么多,这么紧急,保证完成需求都已经非常困难了,已经没精力再编写测试代码了。

现实中,我们经常会针对一些活动开发一些一次性的代码模块,这样的代码模块功能简单,且后续继续迭代的可能性低,这种代码就完全没有必要引入自动化测试工具。

适合引入自动化测试的场景:

  1. 公共库类的开发维护
  2. 中长期项目的迭代/重构
  3. 引用了不可控的第三方依赖

这些场景是需要引入自动化测试来对现有代码进行约束的。尤其是中长期项目,迭代/重构时人力回归困难,自动化测试就显得尤为重要!

如何选择测试工具?

现在市面上有很多流行的测试工具,但普遍都存在一个问题:新特性的支持滞后

前端测试的框架可谓是百花齐放。

  • 单元测试(Unit Test)有 Mocha, Ava, Karma, Jest, Jasmine 等。
  • 集成测试(Integration Test)和 UI 测试(UI Test)有 ReactTestUtils, Test Render, Enzyme, React-Testing-Library, Vue-Test-Utils 等。
主流测试工具比较
框架断言仿真快照异步测试
Mocha默认不支持,可配置默认不支持,可配置默认不支持,可配置友好
Ava默认支持不支持,需第三方配置默认支持友好
Jasmine默认支持默认支持默认支持不友好
Jest默认支持默认支持默认支持友好
Karma不支持,需第三方配置不支持,需第三方配置不支持,需第三方配置不支持,需第三方配置
Mocha
  • Mocha 是生态最好,使用最广泛的单测框架,但是他需要较多的配置来实现它的高扩展性。
Ava
  • Ava 是更轻量高效简单的单测框架,但是自身不够稳定,并发运行文件多的时候会撑爆 CPU。
Jasmine
  • Jasmine 是单测框架的“元老”,开箱即用,但是异步测试支持较弱。
Jest
  • Jest 基于 Jasmine, 做了大量修改并添加了很多特性,同样开箱即用,但异步测试支持良好。
Karma
  • Karma 能在真实的浏览器中测试,强大适配器,可配置其他单测框架,一般会配合 Mocha 或 Jasmine 等一起使用。

每个框架都有自己的优缺点,没有最好的框架,只有最适合的框架。Augular 的默认测试框架就是 Karma + Jasmine,而 React 的默认测试框架是 Jest。

Jest 被各种 React 应用推荐和使用。它基于 Jasmine,至今已经做了大量修改并添加了很多特性,同样也是开箱即用,支持断言,仿真,快照等。Create React App 新建的项目就会默认配置 Jest,我们基本不用做太多改造,就可以直接使用。

采用何种测试思想?

TDD:Test-Driven Development(测试驱动开发)
  • TDD:Test-Driven Development(测试驱动开发):TDD 则要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行
BDD:Behavior-Driven Development(行为驱动开发)
  • BDD:Behavior-Driven Development(行为驱动开发):BDD 可以让项目成员(甚至是不懂编程的)使用自然语言来描述系统功能和业务逻辑,从而根据这些描述步骤进行系统自动化的测试

Jest 基本语法

由于大厂普遍使用 React/Vue 进行开发,而 React/Vue 官方推荐的单元测试工具都是 Jest,因此本文我们就简单介绍一下 Jest 的基本语法。

匹配器

Number

String

Array & Iterable

Exception

异步代码测试

生命周期钩子

生命周期钩子执行顺序符合洋葱模型。

执行顺序

测试单元/用例执行顺序类似异步队列

函数 Mock

小结

本篇文章介绍了前端自动化测试的一些基本概念和主流测试框架 Jest 的基础用法。

相信看完本篇为文章,你一定对前端自动化测试有了一定的了解。

 

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

  1. 文档获取方式:

  2. 加入我的软件测试交流群:680748947免费获取~(同行大佬一起学术交流,每晚都有大佬直播分享技术知识点)

这份文档,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

以上均可以分享,只需要你搜索vx公众号:程序员雨果,即可免费领取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/769674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【兆易创新GD32H759I-EVAL开发板】 关于LVGL 的内存配置

【兆易创新GD32H759I-EVAL开发板】拥有外部32MB的 SDRAM 在使用LVGL时 可以随意分配大小 但是我们也应该明白 所定义的内存大小的 的一些概念 LVGL中 有单独的 定义 LV_MEM_SIZE 定义内存大小 LVLG 中 在定义 显示程序 接口时 还需要用到 lv_disp_draw_buf_init() 分配显存…

MyBatis框架解析与优化

MyBatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL 语句本身,不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。 什么是 MyBatis? MyBatis 是一个半…

【3D reconstruction 学习笔记】

三维重建 3D reconstruction 1. 相机几何针孔相机摄像机几何 2. 相机标定线性方程组的解齐次线性方程组的解非线性方程组的最小二乘解透镜相机标定带畸变的相机标定 3. 单视图重建2D平面上的变换3D空间上的变换单视测量无穷远点 无穷远线 无穷远平面影消点 影消线单视重构 4. 三…

天艺制盖邀您参观2024第七届世界燕窝及天然滋补品博览会

2024第七届世界燕窝及天然滋补品博览会 2024年8月7-9日| 上海新国际博览中心 上海燕博会 世界燕窝及天然滋补品展览会暨世界滋补产业生态发展大会(简称上海燕博会),2017年创办于中国上海,是一年一度的世界燕窝滋补品行业盛会。…

宁波中墙建材施工过程中,如何确保陶粒复合砌块的垂直度和水平度符合要求?

宁波中墙建材陶粒复合砌块如何使用 确保陶粒复合砌块施工质量的建议: 基层处理:在施工前,确保基层干净、平整、坚固,去除表面的杂物和油污等。 砌块质量:选择质量好、尺寸规格一致的陶粒复合砌块,避免使用有…

【串口开发】android 智能设备开发 知识笔记

1.一般的波特率选择115200,自己玩的可以用9600等随便的 2.为了android方便操作,引入了 implementation com.licheedev:android-serialport:2.1.3包。 不然就得手写了,比如像这样 ,打开串口监听 // 打开串口boolean openSerialPort = mSerialPortManager.setOnOpenSerial…

每天一个数据分析题(二百二十八)

在超参数调参的各种方法中,贝叶斯优化搜索(Bayesian Optimization)是一种非常有效的方法。请问在贝叶斯搜索中,用于估计目标函数并为下一次迭代提供建议的模型是什么? A. 线性回归 B. 随机森林 C. 高斯过程 D. 神经网络 题目来源于CDA模…

vue js有哪些优点和缺点

Vue.js 是一个流行的前端 JavaScript 框架,用于构建用户界面和单页面应用。以下是 Vue.js 的一些主要优点和缺点: 优点: 轻量级和简洁:Vue.js 的核心库专注于视图层,并且非常轻量,这使得它可以很容易地与其…

java算法题每日多道六

138. 随机链表的复制 题目 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对…

JS异步操作

点击按钮触发onScan函数,函数调用扫描二维码这个异步操作后,需要扫描二维码的函数返回结果,可以用Promise来实现。Promise对象状态变为resolved(成功)或rejected(失败),然后将解决&a…

运放PSRR与开关电源纹波分析的实际案例分享!

本文来自看海原创视频教程:《运放秘籍》运算放大器基础精讲及应用第一部*开天 微信公众号:工程师看海 【淘宝】https://m.tb.cn/h.5PAjLi7?tkvmMLW43KO7q CZ3457 「运放秘籍_运算放大器Multisim仿真视频教程第一部开天_工程师看海」 点击链接直接打开 …

前端逻辑错误或UI崩溃解决问题

全屏错误覆盖层或UI崩溃 VueReact(错误边界) Vue Vue的全屏错误覆盖层解决,其实只需要配置Error就好,在开发服务器的client.overlay中设置关闭全屏覆盖层 module.exports {devServer: {client: {overlay: {warnings: false,error…

安卓面试题多线程41-45

41. Java中都有哪些同步器?1.synchronized关键字   在Java中,使用synchronized关键字可以对代码块或方法进行同步,使得在同一时刻只有一个线程可以执行该代码块或方法。   下面是一个使用synchronized关键字同步的示例代码: public class SynchronizedExample {private…

Android下的Touch事件分发详解

文章目录 一、事件传递路径二、触摸事件的三个关键方法2.1 dispatchTouchEvent(MotionEvent ev)2.2 onInterceptTouchEvent(MotionEvent ev)2.3 onTouchEvent(MotionEvent event) 三、ViewGroup中的dispatchTouchEvent实现四、总结 在Android系统中,触摸事件的分发和…

k8s入门到实战(一)—— kubernetes概述

k8s 概述 k8s github地址:https://github.com/kubernetes/kubernetes 官方文档:https://kubernetes.io/zh-cn/docs/home/ k8s,全程是 kubernetes,这个名字源于希腊语,意为"舵手"或"飞行员” k8s 这…

mysql忘记root密码

一、用安全模式启动mysql 在 my.ini(windows的安装目录)或 /etc/my.cnf(linux) 的最后一行添加 skip-grant-tables1 重启mysql服务 systemctl restart mysqld 二、创建admin用户 免密码使用root登录进去 $ mysql -uroot 创建…

启动性能优化

一、应用启动慢的原因 1.在主线程执行了太多耗时的操作,比如加载数据,或者初始化三方库等等,导致在Application的oncreate或者Activity的oncreate方法中耗时太久 2.布局嵌套太深,或者一些不会立即使用的布局也在一开始一起加载到…

Linux-Miniconda安装

下载miniconda安装文件 get "https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh" -O ~/miniconda.sh 如果是其它系统或者架构,访问地址获取对应安装脚本: https://mirrors.tuna.tsinghua.edu.cn…

Offlian RL: Weighted Policy Constraints for Offline Reinforcement Learning

AAAI 2023 paper Intro 分布偏移导致离线RL对于OOD数据存在过估计问题。因此一些方法限制策略靠近行为策略。但是着很大程度受限于数据集的质量。若是数据集存在非专家,一个自然的问题是是否有可能构建一个更合理的策略约束方法,该方法通过识别数据集中…

面试算法-111-课程表 II

题目 现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。 例如,想要学习课程 0 ,你需要先完成…