前端自动化测试入门教程

🪴 背景

前端的自动化测试主要可以分为以下四种:

  • 单元测试(Unit Test):对一个函数/组件进行测试,一般用于公共函数/公共组件的测试维护。常用框架有 Jest、Jasmine、Mocha等;

  • 集成测试(Integration Test):对多个模块作为一个整体进行测试,一般用于耦合度较高的函数/组件、经过二次封装的函数/组件、多个函数/组件组合而成的函数/组件等。常用的框架有ReactTestUtils、Enzyme、Vue-Test-Utils 、React-Testing-Library等;

  • UI测试:是对界面样式和交互的测试。

  • 端到端测试(end to end,简称e2e):模拟用户操作的黑盒测试。设定一系列操作,测试系统是否能够按照我们设置的步骤正确执行,可以完整测试整个功能的运行。常用的框架有 Puppeteer、Cypress、Playwright(微软出品,配合vscode插件使用)、Selenium 、cucumber、TestCafe等。

前端开发一般也就单元测试用到比较多,像e2e这种测试几乎不会用到。

确实,因为e2e测试也有一定的开发成本,再好的东西也得适用不是。

那么什么情况下适合引入自动化测试呢?例如以下三个场景:

  • 公共类库、公共组件的开发维护;
  • 中长期项目的迭代/重构;
  • 引用了不可控的第三方依赖;

举个例子,项目中有一个非常重要的下单页面,经过长期的功能迭代重构,核心逻辑可能没变,但是新增了很多新功能,也修改了部分旧功能,已经是一个非常重要的屎山页面。

这时候要你接手这个页面做一些调整,你能保证捋清并且不破坏掉以前的代码逻辑逻辑吗?我敢说你不敢保证,修改点代码生怕造成“事故”,全公司通报。

这时候自动化测试的重要性就体现了,如果在开始就设计好一套核心逻辑的自动化测试脚本,那么在之后迭代的过程中不仅可以通过跑测试脚本缕清逻辑,并且还能在修改代码后用脚本验证自己是否破坏了核心的逻辑。

本文和大家讲解一下e2e自动化测试框架 – puppeteer的基础使用教程。

🌻 教程

1. Puppeteer是什么?

Puppeteer 是一个 Node.js 库,使用它可以运行一个无头的谷歌浏览器(即不显示图形用户界面的浏览器)。然后我们就可以在运行的浏览器中启动我们的页面,并且通过 Puppeteer 提供的 API 操作页面了。

Puppeteer默认是以 headless 无头模式运行,在写测试脚本的时候,为了方便看到效果,可以配置关闭无头模式,即可正常打开浏览器看到页面自动操作的效果。

2. Puppeteer能做什么?

基本上我们平常在浏览器中进行的操作都可以用 Puppeteer 模拟操作,例如:

  • 操作dom,执行dom的各种点击,移动等事件;
  • 模拟键盘输入,鼠标操作。触摸移动等一系列操作;
  • 捕获网站的timeline trace,分析网站性能;
  • 网页截图,生成 PDF;
  • 抓取 SPA(单页应用)并生成预渲染内容(即“SSR”(服务器端渲染))
    等…

3. Puppeteer怎么上手?

(1) 首先安装 Puppeteer

安装 Puppeteer 时会安装一个内置的 Chromium 浏览器,国内用 npm 安装会报错失败,装不上 Chromium,可以改用 yarn 或者 cnpm 安装。

puppeteer还提供了一个轻量级的包—puppeteer-core,这个包不需要下载 Chromium,而是直接启动现有浏览器或连接到远程安装。

yarn add puppeteer
//或者
cnpm i puppeteer

(2) 上手

先 require 引入 puppeteer

const puppeteer = require('puppeteer');

然后开始使用 puppeteer 启动一个浏览器并操作页面。首先需要创建一个 Browser 实例,打开页面,然后使用就可以使用 Puppeteer 的 API 进行你想要的操作了。

const puppeteer = require('puppeteer');(async () => {  //首先创建一个 Browser 实例const browser = await puppeteer.launch();  //然后创建一个 tab页的 Page 实例const page = await browser.newPage();  //然后可以打开我们的网页了await page.goto('https://example.com');  
})();

可以看到我们用了 async / await 语法,是的,在 puppeteer 中,几乎所有操作都是异步的,所以一般使用时需要频繁的用到 async / await ,所以使用前要检查 Node 版本大于 v7.6.0。

如果你需要手动下载 Chromium,还可以配置 Chromium 或 Chrome 可执行文件的位置。

const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'});

正如我们上面所说,怎么关闭 puppeteer 的无头模式呢?只需要在实例化时配置即可。

  //关闭无头模式const browser = await puppeteer.launch({headless: false}); 

配置无头模式之后,我们就可以看到puppeteer会调起一个可视的 Chromium 或 Chrome 浏览器了,这样方便我们直观的看到效果。但是由于puppeteer的操作一步接一步,速度非常快,可能看不清,所以可以使用slowMo参数配置延迟每步操作的时间,如下:

  //关闭无头模式const browser = await puppeteer.launch({headless: false,slowMo: 1000}); 

4. Puppeteer的 API

puppeteer 常用的实例有以下几种:

  • Brower(浏览器实例):Puppeteer通过 launch
    connect 方法连接到 Chromium 时创建一个浏览器实例;可以执行浏览器断开连接、重连、关闭浏览器、打开tab页、获取useragent代理信息等操作;
  • Page(tab页实例):Brower实例通过newPage方法打开一个tab页。关于页面内容的操作一般都会用到这个实例,例如截图、操作dom、跳转tab页、关闭tab页、延迟操作。凡是和页面元素相关的基本都是用它。
  • Keyboard(键盘实例):模拟键盘操作
  • Mouse(鼠标实例):模拟鼠标操作
  • Touchscreen(触屏操作):模拟触屏操作
  • Frame窗口实例

我这里就简单说明几个常用操作,详细的 API 使用可以查看官网文档

(1)获取元素 page.$()、page.$$()

page.$()相当于 document.querySelector,返回匹配的元素节点的第一个。比如获取按钮,然后执行点击事件:

let submitBtn = await page.$("#submit");
submitBtn.click()

page.$$(selector) 相当于 document.querySelectorAll,返回所有匹配的元素节点。

let inputArr = await page.$$('input')

(2)获取元素属性 page.$eval()、page.$$eval()
获取元素属性不能像平常写js那样,获取到元素之后,用dom.value获取它的值或者获取其他属性。可以使用 page. e v a l ( ) 或 p a g e . eval() 或 page. eval()page.$eval() 获取元素属性,区别和上面获取元素雷同。

$eval()是对单个元素进行操作。

$$eval()是对匹配到的所有元素进行操作。

//获取输入框的值
const value = await page.$eval('input[name=search]', input => input.value)
//获取输入框的个数
const num = await page.$$eval('input', input => input.length)

(3)脚本注入 page.evaluate()

如果要执行某段自定义的js代码,可以用page.evaluate()方法。
例如按钮点击你也可以这么写:

await page.evaluate(() => document.querySelector("#submit").click() )

(4) 执行等待
有时候可能需要延迟代码执行,例如修改了元素的可见性,需要等元素显示出来再执行操作,就可以用page.waitForSelector延迟代码执行。常用的延迟执行的api有:

  • page.waitForSelector():等待选择器解析的页面元素出现在页面中;
  • page.waitForNavigation():等待页面跳转后;
  • page.waitForXPath():等待 xpath 解析的页面元素出现在页面中;
  • page.waitForFunction():等待放到页面上下文执行的方法返回真值;
  • page.waitForRequest():等待页面上发起的请求满足判断条件并返回真值;
  • page.waitForResponse():等待页面上接收的请求响应满足判断条件并返回真值;
  • page.waitFor():可充当 page.waitForXPath、page.waitForSelector 、page.waitForFunction 和延时效果用。

(5)page实例分为三个管理模块

  • _frameManager : 管理页面相关行为,例如页面跳转(goto),等待加载(waitFor), 元素选择与处理(evaluate)等
  • _networkManager : 管理网络相关行为,例如请求拦截(setRequestInterception):离线模式(setOfflineMode)等
  • _emulationManager - 管理模拟行为,例如修改浏览器的UserAgent代理信息,修改视窗大小等

👣 实操

我这里写一个简单的小案例,方便大家理解。

打开掘金搜索到我的主页,进入个人主页并截图

创建 check.js,具体的操作步骤看下面代码里的注释:

const puppeteer = require('puppeteer');(async () => {//创建 brower 实例,关闭无头模式,方便查看效果,同时可以设置 slowMo ,放慢自动化操作。const browser = await puppeteer.launch({headless: false,slowMo: 0});//创建 page 实例const page = await browser.newPage();//设置视口宽高const viewWidth = 1000const viewHeight = 800await page.setViewport({width: viewWidth,height: viewHeight,});//跳转掘金首页await page.goto('https://juejin.cn/');//使用 type 方法向掘金搜索框输入 “前端阿彬”await page.type('.search-input','前端阿彬',{delay: 300})//使用 keyboard 类的 press 方法模拟键盘按下 "Enter" 键await page.keyboard.press('Enter');//这里一定要用 waitForSelector 方法等搜索结果显示出来再继续操作await page.waitForSelector('.nav-item.route-active')//点击搜索结果的 “用户” tabawait page.evaluate(() => document.querySelectorAll(".nav-item.route-active>a")[4].click() )//等用户列表显示出来再继续操作await page.waitForSelector('.main-list .item')//获取第一个item,也就是我的个人主页的a链接地址const href = await page.$$eval('.main-list .item a',link => link[0].href)//获取到个人主页的href,然后用goto跳转await page.goto(href);//等待页面跳转完成再继续操作page.waitForNavigation()//调用 screenshot 方法进行截图,并裁减可视区域内的部分await page.screenshot({path: '个人主页.png',clip: {x: 0,y: 0,width: viewWidth,height: viewHeight,}});//关闭浏览器await browser.close();
})();

命令行执行 node check.js 执行我们的测试脚本,效果如下:

tutieshi_640x668_9s.gif

截图如下:

个人主页.png

最后

puppeteer的功能非常强大,基本上平常在浏览器里能手动完成的操作都可以用它模拟。而测试脚本逻辑无非就是调用它的 API,实际逻辑其实还是靠js,所以上手并不难。

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

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

相关文章

JMeter数据库性能测试指南:全面掌握基础操作

1.网络请求时间 2.数据库查询的时间 数据库性能指标 TPS:每秒事务数(一秒钟服务器处理的事务数,事务指,请求出去到响应回来的整个过程的时间) QPS:每秒查询量(就是数据库每秒执行的SQL数量,包含insert/…

intel深度相机 D455及D4系列入门教程(逐行代码讲解)

1.介绍 Intel RealSense D435、D455等D4系列: Intel D4系列深度相机是由英特尔(Intel)公司推出的一款深度感知摄像头,专为实现计算机视觉和深度学习应用而设计。这款相机使用了英特尔的深度感知技术,结合了摄像头和红…

vue3+elementPlus el-input的type=“number“时去除右边的上下箭头

改成 代码如下 <script lang"ts" setup> import {ref} from vue const inputBtn ref() </script> <template><el-input type"number" v-model"inputBtn" style"width: 80px;" class"no_number">…

WPS/word 表格跨行如何续表、和表的名称

1&#xff1a;具体操作&#xff1a; 将光标定位在跨页部分的第一行任意位置&#xff0c;按下快捷键ctrlshiftenter&#xff0c;就可以在跨页的表格上方插入空行&#xff08;在空行可以写&#xff0c;表1-3 xxxx&#xff08;续&#xff09;&#xff09; 在空行中输入…

毛玻璃 has 选择器卡片悬停效果

效果展示 页面结构 从上述的效果展示可以看到&#xff0c;页面是由多个卡片组成&#xff0c;并且鼠标悬停在卡片上时&#xff0c;会旋转用户图片并且韩式对应的用户信息框。 CSS3 知识点 :has 属性的运用 实现页面整体结构 <div class"container"><div…

RT-Thread 内存管理(学习二)

内存堆管理应用示例 这是一个内存堆的应用示例&#xff0c;这个程序会创建一个动态的线程&#xff0c;这个线程会动态申请内存并释放&#xff0c;每次申请更大的内存&#xff0c;当申请不到的时候就结束。 #include <rtthread.h>#define THREAD_PRIORITY 25 #defi…

conda安装使用jupyterlab注意事项

文章目录 一、conda安装1.1 conda安装1.2 常见命令1.3 常见问题 二、jupyterlab2.1 jupyterlab安装和卸载2.2 常见错误2.2.1 版本冲突&#xff0c;jupyterlab无法启动2.2.2 插件版本冲突 2.3 常用插件2.3.1 debugger2.3.2 jupyterlab_code_formatter 2.4 jupyter技巧 一、conda…

Docker数据管理

容器中管理数据主要有两种方式&#xff1a; 数据卷&#xff08;Data Volumes&#xff09; 数据卷容器&#xff08;Data Volume Dontainers&#xff09; Docker的数据管理 数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机的目录挂载到数据卷上&…

云服务器CVM_云主机_云计算服务器_弹性云服务器-腾讯云

腾讯云服务器CVM提供安全可靠的弹性计算服务&#xff0c;腾讯云明星级云服务器&#xff0c;弹性计算实时扩展或缩减计算资源&#xff0c;支持包年包月、按量计费和竞价实例计费模式&#xff0c;CVM提供多种CPU、内存、硬盘和带宽可以灵活调整的实例规格&#xff0c;提供9个9的数…

微服务学习(十一):安装Git

微服务学习&#xff08;十一&#xff09;&#xff1a;安装Git 1、下载Git 官网下载Git 2、将下载后的资源包上传到服务器 3、解压并安装 tar -zxvf git-2.42.0.tar.gz4、安装依赖 yum install zlib yum install zlib-devel5、执行操作命令 cd /home/git/git-2.42.0 ./co…

Nginx高级 第一部分:扩容

Nginx高级 第一部分&#xff1a;扩容 通过扩容提升整体吞吐量 1.单机垂直扩容&#xff1a;硬件资源增加 云服务资源增加 整机&#xff1a;IBM、浪潮、DELL、HP等 CPU/主板&#xff1a;更新到主流 网卡&#xff1a;10G/40G网卡 磁盘&#xff1a;SAS(SCSI) HDD&#xff08;机械…

使用springboot服务端远程调试? 试试HTTP实现服务监听

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《初阶数据结构》《C语言进阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 wi…