自动化测试倒退
提起自动化大家肯定不会生疏,工业自动化、办公自动化、测试自动化,毕竟解放双手是从今人那里就开始传承下来的传统。比方今人的造纸术、活字印刷术,以及各种农业生产工具,无论今人还是当下的咱们,都在一直寻找各种工具来解放双手。
什么是自动化测试
百度百科会这样通知你
个别是指软件测试的自动化,软件测试就是在预设条件下运行零碎或应用程序,评估运行后果,事后条件应包含失常条件和异样条件。
简略来了解,自动化就是尽可能的模仿人为的操作来对应用程序进行检测,比方你造了一个计算机,那么自动化测试就将会试一试开机是否好用,程序是否能够运行。
前端自动化测试
对于前端自动化测试咱们分为三局部:成果(UI界面)测试、交互测试、单元测试。
- 成果(UI界面)测试
成果测试是指以后的页面成果是否与效果图统一,能够通过计算二者的差别度,进而得出类似度,显然如果相差70%,那必然不会合格,至于多少能够通过,齐全能够自行来指定。
- 交互测试
前端和用户有着频繁的交互,比方用户鼠标单击与挪动,键盘的按下与抬起等等,正是凭借着晦涩且高频的交互,才可能给用户更好的体验。而交互测试要做的,就是模仿用户的操作来点击或者挪动等等。进而判断交互后的后果是否合乎网站开发者的预期。
- 单元测试
单元测试在各个语言的测试框架中都是必不可少的一部分,单元测试是指程序中最小可测试单元,显然,你的我的项目代码耦合度越低,颗粒度越小,那么可测试的单元就越多,就跟答题一样,验算做的多,每个步骤的验算越精确,是不是正确性就越高呢,单元测试就是这个情理。
成果(UI界面)测试
想要实现页面的成果测试能够分为以下步骤:
- 筹备好效果图用于比对
- 看待检测的页面进行截图
- 通过像素比看待检测页面截图与效果图得出差别占比
- 自定义通过比例,给出敌对提醒
后期筹备
咱们通过 puppeteer
看待检测页面进行截图,通过 blink-diff
来比对两张图的差别,在开始应用前,须要进行如下装置:(当然,这一些都要求你本地曾经装置好了 Node.js
环境)
npm install -g puppeteernpm install -g blink-diff
应用步骤
引入已装置的库
const puppeteer = require('puppeteer'), BlinkDiff = require('blink-diff')
通过
puppeteer
看待检测页面进行截图const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });const page = await browser.newPage();await page.setViewport({ width: 1920, height: 945 });await page.goto('http://www.baidu.com');await page.screenshot({ path: imgUrl + 'Screenshots.png', fullPage: true });//敞开puppeteerbrowser.close();
通过
blink-diff
来比对两张图的差别const diff = new BlinkDiff({ imageAPath: imgUrl + 'example.png', // 设计图 imageBPath: imgUrl + 'Screenshots.png',//页面截图 threshold: 0.02, // 1% threshold imageOutputPath: imgUrl + 'Diff.png'//Diff门路 }); diff.run(function (error, result) { if (error) { throw error; } else { let rel = Math.round((result.differences / result.dimension) * 100) console.log(diff.hasPassed(result.code) ? '通过' : '失败'); console.log('总像素:' + result.dimension); console.log('发现:' + result.differences + ' 差别,差别占比' + rel + "%"); if (rel > 20) { process.exit(1); } } });
比对实现后,会在 images 文件夹中生成比照差别图片,不过,咱们临时并用不到它。
Selenium-webdriver 交互测试
想要实现页面的交互测试能够分为以下步骤:
- 筹备待检测的页面
- 布局要检测的交互,比方简略导航条的鼠标悬浮后成果
- 编写检测脚本
- 下载浏览器驱动
- 启动测试与敌对提醒
后期筹备
咱们通过 selenium-webdriver
实现页面交互检测(当然,这一些都要求你本地曾经装置好了 Node.js
环境)
npm install selenium-webdriver
后期筹备第二件十分重要的事件就是下载浏览器驱动,本系列应用 Chrome 浏览器进行测试,下载驱动地址如下
http://chromedriver.storage.googleapis.com/index.html
这里须要特地留神的是:保障下载的 Chrome 浏览器版本与下载的浏览器驱动版本统一。本节中应用的版本为 91.0.4472.19 (这里的版本并不必和我对立,和你本机的 Chrome 版本对立即可)
应用步骤
提前创立一个 index.js
文件,用于写入下列代码。
- 创立
WebDriver
实例
无论你是心愿测试鼠标单击还是键盘按下,第一件事须要做的都是先创立 WebDriver
实例
var webdriver = require('selenium-webdriver')var driver = new webdriver.Builder() .forBrowser('chrome') .build();
- 关上须要检测的地址
driver.get('http://www.baidu.com');
- 操作页面元素
webdriver.By.id('kw').sendKeys('webdriver');webdriver.By.id('su').click();
最初,通过 node index.js
就能够执行该文件,能够看到弹出一个 Chrome 浏览器窗口,主动在搜寻框中输出 了 webdriver
并单击了搜寻按钮, 成果如下。
这一部分咱们仅初体验了下 selenium-webdriver 的性能,与理解了它的应用步骤。但仅下面这点性能远远无奈理论业务中场景,这就须要理解更多的 API ,滚动鼠标,持续向下看。
罕用API
selenium-webdriver 提供了丰盛的 API ,想要理解更全面的小伙伴,能够戳这里 。本大节仅对罕用的 API 进行介绍。咱们能够依据 API 的性能分为以下几类。
- 页面操作
- 定位元素
- 获取元素信息
- 事件操作
接下来,一一意识下
页面操作
函数名称 | 形容 | 示例代码 |
---|---|---|
get() | 申请指定的 URL | driver.get("http://www.baidu.com") |
getTitle() | 检索以后网页题目 | driver.getTitle().then(val => { console.log(val) }); |
getCurrentUrl() | 检索当前页的URL | driver.getCurrentUrl().then(val => { console.log(val) }); |
getPageSource() | 检索当前页的源代码 | driver.getPageSource().then(val => { console.log(val) }) |
quit() | 终止浏览器会话。在调用quit之后,该实例将生效,并且可能不再用于对浏览器收回命令 | driver.quit() |
定位元素
- 通过
By
类提供的函数来进行定位元素,By
类在 selenium-webdriver 下,惯例用法如下:
//第一种var webdriver = require('selenium-webdriver')let kw=webdriver.By.id('kw');//第二种var webdriver = require('selenium-webdriver'), By = webdriver.Bylet kw=By.id('kw');
By
类提供的动态函数:
动态函数 | 形容 | 示例代码 |
---|---|---|
By.className( name ) | 定位具备特定类名的元素 | By.className('s_ipt') |
By.css( selector ) | 应用CSS选择器定位元素 | By.css('s_ipt') |
By.id( id ) | 应用ID选择器定位元素 | By.id('kw') |
By.linkText( text ) | 定位其可见文本与给定字符串匹配的链接元素 | By.linkText("AboutGoogle") |
By.name( name ) | 定位name属性具备给定值的元素 | By.name("btnK") |
By.partialLinkText( text ) | 定位其可见文本蕴含给定子字符串的链接元素。 | By.partialLinkText("About") |
By.xpath( xpath ) | 定位与XPath选择器匹配的元素 | By.xpath(“//*[text()=’退出’]) |
- 通过
findElement
定位页面上的元素。如果找不到元素,则出错。
var e1 = driver.findElement(By.id('foo'));var e2 = driver.findElement({id:'foo'});
下面的两句代码作用是等同的,除此之外还能够自定义一个函数来定位元素,比方像上面这样。
var link = driver.findElement(firstVisibleLink); function firstVisibleLink(driver) { var links = driver.findElements(By.tagName('a')); return promise.filter(links, function(link) { return link.isDisplayed(); }); }
findElement
还有一个兄弟就是 findElements
如果你须要搜寻页面上的多个元素或须要测试元素是否呈现在页面上,能够思考它。
var e1 = driver.findElements(By.tagName("input")
获取元素信息
定位到元素之后,一个十分高频对操作就是获取元素信息。
函数名称 | 形容 | 示例代码 |
---|---|---|
getCssValue() | 获取CSS属性值 | element.getCssValue("background-color").then((val) => { console.log(val) } |
getAttribute() | 获取其余属性 | element.getAttribute("id").then((val) => { console.log(val) } |
事件操作
交互测试最重要的一点就是用户与页面之间的交互,比方鼠标事件、键盘事件。
事件 | 形容 | 示例代码 |
---|---|---|
click() | 鼠标点击事件 | element.click() |
doubleClick() | 鼠标双击事件 | element.doubleClick() |
keyDown() | 键盘按下 | element.keyDown() |
keyUp() | 键盘抬起 | element.keyUp() |
sendKeys() | 插入一系列操作以键入所提供的键序列。对于每个键,这将记录一对keyDown和keyUp动作 | element.keyUp.sendKeys('webdriver') |
如果上述的事件无奈满足你的需要,比方想要测试鼠标移入与移出事件,应该来做?我将介绍一个万能的函数,相对能够满足任何性能,也就是 executeScript
。
driver.executeScript("document.getElementById('item').onmouseover()")
上述代码会在以后选定的框架或窗口的上下文中执行JavaScript代码片段。脚本片段将作为匿名函数体执行。能够执行代码片段,是不是任何操作都难不住你了。
示例:检测鼠标点击后扭转色彩
需要很简略,首先有一个页面,而后下面有一个 div 元素,单击 div 元素后,能够扭转 div 的背景色彩,这一系列步骤如何利用自动化检测来实现呢。要害代码如下:
async function checkClick() { driver.get('http://127.0.0.1:8080'); let item; await driver.findElements(By.id('item')).then( function(val) { //判断元素是否存在 if (val.length == 0) { console.log("没有找到元素,检测失败"); process.exit(1); } item = val[0]; }) item.click(); await item.getCssValue("background-color").then( function(val) { if (val != "rgba(255, 239, 161, 1)") { console.log("检测失败") process.exit(1); } else { console.log("检测胜利") } }) driver.quit();}
Jest 单元测试
单元测试是指程序中最小可测试单元,在 JavaScript 中最小可测试单元就是函数了,所以咱们重点来介绍如何利用测试框架来测试函数。
后期筹备
咱们通过 jest
实现函数测试,先须要做的就是装置了
npm install -g jest
应用步骤
- 先来筹备一个待测试的 cal.js 文件
function cal(num1, num2, type) { var result; switch (parseInt(type)) { case 0: result = num1 + num2; break; case 1: result = num1 - num2; break; case 2: result = num1 * num2; break; case 3: result = num1 / num2; break; } return result;}module.exports = cal;
文件中蕴含了一个 cal 函数,实现了一个繁难计算器
编写测试文件,cal.test.js ,个别命名的时候以在待测试文件的前面跟上 test 结尾
const cal = require('./cal.js');test('1 + 2 = 3', () => { expect(cal(1, 2, 0)).toBe(3);});test('5 - 2 = 3', () => { expect(cal(5, 2, 1)).toBe(3);});test('1 * 2 = 2', () => { expect(cal(1, 2, 2)).toBe(2);});test('4 / 2 = 2', () => { expect(cal(4, 2, 3)).toBe(2);});
- 通过 npm init 一路回车,初始化 package.json 文件,写入如下内容
{ "scripts": { "test": "jest" }}
- 通过
jest cal.test.js
启动测试
罕用API
在测试过程中,咱们应用最多的就是 expect
,它为咱们提供了许多匹配的办法,使咱们能够轻松实现验证匹配。如果你须要理解更多,能够戳这里。
办法 | 形容 | 示例代码 |
---|---|---|
.toBe(value) | 应用 Object.is 来测试两个值精准相等 | expect(cal(1, 2)).toBe(3) |
.toBeTruthy() | 匹配任何 if 语句为真 | expect(thirstInfo()).toBeTruthy(); |
.toContain(item) | 查看具备特定构造和值的项是否蕴含在数组中 | expect(list).toContain('obj'); |
最初
文章有点长,看到最初如果对你有一丢丢帮忙,要不要点个赞再走?
有须要获取残缺示例代码的小伙伴,请戳这里
PS:文章状态未完结,会随着后续应用持续更新,如果你也有遇到什么问题或者想补充的内容来一起交换交换呀