自动化测试倒退

提起自动化大家肯定不会生疏,工业自动化、办公自动化、测试自动化,毕竟解放双手是从今人那里就开始传承下来的传统。比方今人的造纸术、活字印刷术,以及各种农业生产工具,无论今人还是当下的咱们,都在一直寻找各种工具来解放双手。

什么是自动化测试

百度百科会这样通知你

个别是指软件测试的自动化,软件测试就是在预设条件下运行零碎或应用程序,评估运行后果,事后条件应包含失常条件和异样条件。

简略来了解,自动化就是尽可能的模仿人为的操作来对应用程序进行检测,比方你造了一个计算机,那么自动化测试就将会试一试开机是否好用,程序是否能够运行。

前端自动化测试

对于前端自动化测试咱们分为三局部:成果(UI界面)测试、交互测试、单元测试。

  1. 成果(UI界面)测试

成果测试是指以后的页面成果是否与效果图统一,能够通过计算二者的差别度,进而得出类似度,显然如果相差70%,那必然不会合格,至于多少能够通过,齐全能够自行来指定。

  1. 交互测试

前端和用户有着频繁的交互,比方用户鼠标单击与挪动,键盘的按下与抬起等等,正是凭借着晦涩且高频的交互,才可能给用户更好的体验。而交互测试要做的,就是模仿用户的操作来点击或者挪动等等。进而判断交互后的后果是否合乎网站开发者的预期。

  1. 单元测试

单元测试在各个语言的测试框架中都是必不可少的一部分,单元测试是指程序中最小可测试单元,显然,你的我的项目代码耦合度越低,颗粒度越小,那么可测试的单元就越多,就跟答题一样,验算做的多,每个步骤的验算越精确,是不是正确性就越高呢,单元测试就是这个情理。

成果(UI界面)测试

想要实现页面的成果测试能够分为以下步骤:

  1. 筹备好效果图用于比对
  2. 看待检测的页面进行截图
  3. 通过像素比看待检测页面截图与效果图得出差别占比
  4. 自定义通过比例,给出敌对提醒

后期筹备

咱们通过 puppeteer 看待检测页面进行截图,通过 blink-diff 来比对两张图的差别,在开始应用前,须要进行如下装置:(当然,这一些都要求你本地曾经装置好了 Node.js 环境)

npm install -g puppeteernpm install -g blink-diff

应用步骤

  1. 引入已装置的库

    const puppeteer = require('puppeteer'),    BlinkDiff = require('blink-diff')
  2. 通过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();  
  3. 通过 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 交互测试

想要实现页面的交互测试能够分为以下步骤:

  1. 筹备待检测的页面
  2. 布局要检测的交互,比方简略导航条的鼠标悬浮后成果
  3. 编写检测脚本
  4. 下载浏览器驱动
  5. 启动测试与敌对提醒

后期筹备

咱们通过 selenium-webdriver 实现页面交互检测(当然,这一些都要求你本地曾经装置好了 Node.js 环境)

npm install selenium-webdriver

后期筹备第二件十分重要的事件就是下载浏览器驱动,本系列应用 Chrome 浏览器进行测试,下载驱动地址如下

http://chromedriver.storage.googleapis.com/index.html

这里须要特地留神的是:保障下载的 Chrome 浏览器版本与下载的浏览器驱动版本统一。本节中应用的版本为 91.0.4472.19 (这里的版本并不必和我对立,和你本机的 Chrome 版本对立即可)

应用步骤

提前创立一个 index.js 文件,用于写入下列代码。

  1. 创立 WebDriver 实例

无论你是心愿测试鼠标单击还是键盘按下,第一件事须要做的都是先创立 WebDriver 实例

var webdriver = require('selenium-webdriver')var driver = new webdriver.Builder()     .forBrowser('chrome')     .build();
  1. 关上须要检测的地址
driver.get('http://www.baidu.com');
  1. 操作页面元素
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()申请指定的 URLdriver.get("http://www.baidu.com")
getTitle()检索以后网页题目driver.getTitle().then(val => { console.log(val) });
getCurrentUrl()检索当前页的URLdriver.getCurrentUrl().then(val => { console.log(val) });
getPageSource()检索当前页的源代码driver.getPageSource().then(val => { console.log(val) })
quit()终止浏览器会话。在调用quit之后,该实例将生效,并且可能不再用于对浏览器收回命令driver.quit()
定位元素
  1. 通过 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()=’退出’])
  1. 通过 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

应用步骤

  1. 先来筹备一个待测试的 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 函数,实现了一个繁难计算器

  1. 编写测试文件,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);});
  2. 通过 npm init 一路回车,初始化 package.json 文件,写入如下内容
{    "scripts": {        "test": "jest"    }}
  1. 通过 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:文章状态未完结,会随着后续应用持续更新,如果你也有遇到什么问题或者想补充的内容来一起交换交换呀