收录待用,修改转载已取得腾讯云授权


作者:yangchunwen

首先要解释一下为什么叫浏览器自动化测试,因为本文只关注发布后页面功能的自动化测试,也就是UI层面的自动化。

浏览器测试有别于js代码的单元测试,后者一般是发布前的代码功能逻辑测试,在这方面已经有很多比较成熟的方案,如jasmine mocha Qunit...

为什么要做自动化

个人认为自动化测试的主要出发点有两点:

  • 减少重复的工作。让机器自动帮我们完成需要的交互操作,验证我们的页面功能。

  • 自动监控。通过自动回归我们的页面功能,可以在功能出错的时候提供报警,为我们手动排除问题提供参考。

开胃菜

说到浏览器自动化测试,不得不介绍大名鼎鼎的phantomjscasperjs。phantomjs可以理解为一个无界面的浏览器,可以通过流水线式的代码来驱动其页面的浏览行为,而后者是前者在易用性API上的一些封装。

这里演示下使用casperjs截取百度首页

关于这两个东西的安装,有兴趣体验的建议去看官方文档,其实很简单,这里不一一赘述。

首先创建一个js文件baidu.js

var casper = require('casper').create();
casper.start();
casper.thenOpen('http://www.baidu.com/', function () {
casper.captureSelector('baidu.png', 'html');
});
casper.run();

以上代码主要做了三件事:

  1. 创建一个casperjs实例require('casper').create(),可以理解为一个浏览器进程

  2. 打开一个页面casper.thenOpen(...)

  3. 截取页面图像casper.captureSelector

在命令行运行

casperjs baidu.js

看看此脚本生成的图片结果

等等!为什么这个图只有400X300的大小?

原因是我创建了一个浏览器进程去加载页面,但是没有指明用什么浏览器去加载。所以在创建casper实例的时候,可以指定浏览器的窗口大小,甚至我们可以通过指定userAgent的方式冒充手机端的浏览器。例如我们将其指定为iPhone5的safari,并设置窗口大小:

var casper = require('casper').create({
pageSettings: { // 冒充浏览器
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53'
}, // 浏览器窗口大小
viewportSize: {
width: 320,
height: 568
}
});

再次运行后我们的是这样,是不是手机浏览时的样子了?

简单应用

以上的例子,可以知道了怎么使用一个无界面的浏览器去加载页面,并获得页面的界面截图。

我们可以不打开浏览器,一行命令就可以知道页面长啥样了,所以每次我们只要运行这个casperjs脚本,通过截图就能看到我们页面是不是正常的。

但是,通过肉眼去判断,肯定是有违“自动化”的初衷的,所以必须要借助工具来帮我们分析。

最简单直观的办法就是“像素对比”,也就是把两次或多次的截图,逐一对比每一像素或一定范围区域,这样就能产出图片的差别了,如下图:

实际应用中,可以指定一个图片作为基准图,每一次我们截取的页面图与之对比,如果不一样,就可以说明线上的页面出现了异常。

像素对比这样的工具已经比较成熟,这里介绍一个与前端开发非常亲近的方案:Resemble.js

为什么说它和前端亲近,因为它使用的是canvas。我们知道,每一个图片的每一像素,都可以通过RBGA(red,blue,green,alpha)三个值来确定:

Resemble.js的主要原理就是把我们需要对比的图片绘制到canvas中,读取需要对比的像素点(或区域)的image data,从而确定图片的差异。

为了与phantomjs/casperjs更好的结合,Resemble.js作者同时做了基于Resemble.js的封装phantomcss

phantomcss使用了简单的API来做图片对比:

phantomcss.screenshot( "#CSS .selector1", screenshotName1);
phantomcss.screenshot( "#CSS .selector2", screenshotName2);
phantomcss.compareFiles(screenshotName1, screenshotName2);

假如对比的图片有不一致的地方,会生成一张对比图,同时有差异的地方会用显眼的颜色标出,类似这样:

注意

页面截图对比出现不一致,并不能证明我们的页面就出现了异常,例如广告位等,这些变化频繁的区域,每一次对比都有可能出现差异,所以对广告位或其他经常变化的位置不宜所差异对比。

实际应用中,对整个页面进行截图对比是不推荐的,这样的方式过于简单粗暴,我们更应该对页面的各个区域进行细分对比,做细粒度的监控。

cookie

既然是浏览器测试,不能没有cookie的参与,casperjs没有对cookie的操作作封装,可以使用phantomjs直接“种”cookie:

phantom.addCookie({
name: 'cookie',
value: 'value',
domain: '.xx.com',
path: '/',
secure: false,
httponly: false,
expires: Date.now() + (1000 * 60 * 60 * 24 * 5)
});

在前面的开胃菜中,我们访问到的页面都是没有登录态的,这里通过手动植入百度帐号登录态的cookie值来实现登录访问。

在PC端chrome中打开百度首页,并用你的帐号登录,在开发者工具中复制百度帐号关键cookie BDUSS的值

并hard code到你的casperjs脚本中:

phantom.addCookie({
name: 'BDUSS',
value: '你复制的cookie值',
domain: '.baidu.com',
path: '/',
secure: false,
httponly: false,
expires: Date.now() + (1000 * 60 * 60 * 24 * 5)
});

完整代码看这里

运行之后我们再看一下结果

Done!右上角已经有用户名,说明此时我们已经登录了!

交互

简单的截图+对比还远远达不到我们的测试要求,对于自动化原则来说,为我们实现自动化的页面交互才是王道,别急,这就来。

前面介绍了手动种植cookie的方式实现登录,下面看下怎么实现手机端百度的登录过程。

先预览下整个脚本login.js的代码,下面解释一下整个过程:

1. 创建实例。与开胃菜中的配置基本一致,这里为了更快,实例化的配置选择了不加载图片
loadImages: false

2. 加载页面
3. 截取无登录态的页面:
casper.captureSelector('1.png', 'html');

这一步会得到图片1.png,并且右上角是没有用户名的(未登录):

4. 读取当前的所有cookie并输出
var cookies = phantom.cookies;
for (var i = 0, len = cookies.length; i < len; i++) {
console.log(cookies[i].name + ': ' + cookies[i].value);
}

这一步输出到命令行的结果:

可以看到,当前的cookie中还没有百度账号的关键cookie BDUSS。

5. 点击登录按钮
casper.mouse.click('#login');

casperjs(phantomjs)支持了非常丰富的可以支持复杂交互的鼠标事件:

  • click
  • doubleclick
  • rightclick
  • down
  • up
  • move

鼠标事件支持指定操作目标的CSS3路径

6. 点击登录后,会跳转到一个填写用户名和密码的登录页,这里为了方便,强行等待3秒确保登录页加载完
casper.wait(3000);

7. 截取登录页界面
casper.captureSelector('2.png', 'html');

8. 填写表单
casper.evaluate(function () {
document.querySelector('[name=username]').value = '***';
document.querySelector('[name=password]').value = '***';
});

这里使用了一个非常有用的方法evaluate

9. 截取填写登录表单后的样子
10. 点击登录按钮
11. 等待跳转回首页
12. 截取登录后的首页界面
13. 逐一读取cookie并显示到命令行中

最后,运行测试脚本casperjs login.js能得到4张截图,分别记录了整个登录交互过程中关键步骤的交互效果:

对比图1和图4,区别在于图4右上角的用户名:

同时,在命令行中最后还读取到了登录后的BDUSS cookie值:

再来点猛料

  • iframe里的操作

phantomjs(casperjs)不仅可以在当前页面操作,还可以把当前context切换到iframe里进行操作,这点给嵌入iframe的页面测试带来了很多方便。

  • 操作区域

phantomjs(casperjs)支持使用CSS3选择器及XPath的方式对我们需要操作的目标进行操作(点击、截图等),还可以通过指定区域边界的来操作,例如可以指定x/y坐标/width/height来进行点击或截图等:

casper.capture('capture.png', {
x: 200,
y: 300,
width: 200,
height: 300
});

交互的一些局限

现实世界的web里,有些交互功能不是机械的操作,有时候出于安全或其他因素考虑,页面会做一些限制,要求我们的交互需要根据一些动态输出,这种功能是很难做到完全自动化的,例如,上面的百度登录功能,有时候会出现验证码的情况:

这时候就很难借助机器来帮我们做登录了,所以在前面我要介绍通过手动植入cookie的方式实现登录。

单元测试

通过前面的介绍,使用phantomjs(casperjs)已经能实现很多自动化的功能,在此基础上,实现单元测试就很简单了。

casperjs提供了相对比较完善的单元测试API

单元测试中,每一个testsuite都被包装在一个闭包中:

casper.test.begin('your testsuite', 0, function (test) {
// 单元测试代码
});

例如下面是一个测试百度页面title及log位置是否正确的一组测试用例:

casper.test.begin('test demo', 0, function (test) {

    casper.start();

    casper.thenOpen('http://www.baidu.com/', function () {

        // 测试页面title是否正确
casper.test.assertTitle('百度一下', 'page title'); // 测试logo的位置信息 // 获取x/y/width/height
var layout = casper.getElementBounds('#logo');
layout = JSON.stringify(layout); // 验证是否符合
casper.test.assertEquals(layout, '{"height":87,"left":0,"top":53,"width":320}', 'logo\'s boundary'); }); casper.run(function () {
casper.test.done();
}); });

完整代码test.js在这里

运行casperjs test test.js

可以在命令行中看到以下输出:

两个case都已pass!

与前面的截图肉眼查看的方式相比,单元测试为我们提供了更加简洁的测试结果。

另外,casperjs的test模块还可以在测试后产出XML结果,例如上面那个例子的结果如下:

<?xml version="1.0" encoding="UTF-8" ?>
<testsuites time="2.228">
<testsuite name="test demo" tests="2" failures="0" errors="0" time="2.228"
timestamp="2015-08-31T13:30:12.462Z" package="test">
<testcase name="page title" classname="test" time="2.223">
</testcase>
<testcase name="logo's boundary" classname="test" time="0.005">
</testcase>
<system-out>
</system-out>
</testsuite>
</testsuites>

利用这个XML结果,与报警等系统结合,可以实现各种强大的自动化功能。

问题

  1. 浏览器兼容。

    说到底,phantomjs(casperjs)提供的还是一个无界面的webkit内核浏览器,所以无法覆盖IE浏览器。目前Gecko内核的无界面浏览器已经有解决方案SlimerJS,并且支持与phantomjs一模一样的API。

  2. 设备兼容。

    在各种手机等终端设备良莠不齐的情况下,服务端的无界面浏览器在这点上更难以做到模拟所有的软硬件环境。

原文链接:http://ivweb.io/topic/55e46d8d771670e207a16bdc


原文链接:https://www.qcloud.com/community/article/641602001489391648

浏览器自动化测试初探 - 使用phantomjs与casperjs的更多相关文章

  1. [转] 浏览器自动化测试初探:使用 phantomjs 与 casperjs

    [From] https://www.qcloud.com/community/article/641602001489391648 作者:yangchunwen 首先要解释一下为什么叫浏览器自动化测 ...

  2. PhantomJS、CasperJS安装配置图文详解

    目前网站主流的加载方式: 一种是同步加载:另一种是异步加载,也即我们常说的用ajax.对于同步加载的网站,普通的爬虫程序轻松就能搞定.但是对于那种异步请求数据的网站,通常使用selenium+Phan ...

  3. PhantomJS与CasperJS在Windows下的安装与使用

    按照网上的教程来呢,一定是不好使的,这是常理. 所以必须要告诉你怎么使用Phantomjs…… 这么用! 1.下载Phantomjs的压缩包并解压缩: 2.在bin目录(包含phantomjs.exe ...

  4. [Python爬虫] 在Windows下安装PhantomJS和CasperJS及入门介绍(上)

    最近在使用Python爬取网页内容时,总是遇到JS临时加载.动态获取网页信息的困难.例如爬取CSDN下载资源评论.搜狐图片中的“原图”等,此时尝试学习Phantomjs和CasperJS来解决这个问题 ...

  5. 前端端对端测试:基于PhantomJS的CasperJS

    简介 Casperjs是一个基于PhantomJS和SlimerJS的前端端对端测试框架,当然你也可以使用它完成网络爬虫功能,它的特点的通过简单的脚本模拟浏览器行为, 主要有casper.tester ...

  6. Selenium浏览器自动化测试工具

    目录 Selenium浏览器自动化测试工具 Selenium模块在爬虫中的使用 Python简单使用Selenium Selenium的基本操作 Selenium爬取动态加载的数据 Selenium动 ...

  7. Python3+unitest自动化测试初探(中篇)

    目录 6.生成测试报告 7.编写邮件发送工具 8.发送邮件 发布 0 86 编辑 删除 Python3+unitest自动化测试初探(中篇)(2019-04-18 01:41) 发布 3 245 编辑 ...

  8. Python3+unitest自动化测试初探(下篇)

    目录 9.用例结果校验 10.跳过用例 11.Test Discovery 12.加载用例 unittest官方文档 本篇随笔承接: Python3+unitest自动化测试初探(中篇) Python ...

  9. 第三百三十七节,web爬虫讲解2—PhantomJS虚拟浏览器+selenium模块操作PhantomJS

    第三百三十七节,web爬虫讲解2—PhantomJS虚拟浏览器+selenium模块操作PhantomJS PhantomJS虚拟浏览器 phantomjs 是一个基于js的webkit内核无头浏览器 ...

随机推荐

  1. VS 关于 .sln 文件和 .suo 文件

    VS 关于 .sln 文件和 .suo 文件  Visual Studio.NET采用两种文件类型(.sln和.suo)来存储特定于解决方案的设置,它们总称为解决方案文件.为解决方案资源管理器提供显示 ...

  2. thinkphp5.0模块设计

    5.0版本对模块的功能做了灵活设计,默认采用多模块的架构,并且支持单一模块设计,所有模块的命名空间均以app作为根命名空间(可配置更改). 目录结构 标准的应用和模块目录结构如下: ├─applica ...

  3. innerText和innerHTML, outerHTML

    js中 innerHTML与innerText的用法与区别及解决Firefox不支持Js的InnerHtml问题 用法: <div id="test"> <spa ...

  4. Linux安装apache服务

    1.通过yum包下载安装httpd yum -y install httpd*(等待安装) 到下面就安装完毕 2.启动apache服务 service httpd restart 3.现在就可以查看a ...

  5. RxJava 机制

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha rxjava 是  以 响应式 编程思想   编程的 java类库

  6. POJ 3553 Light Switching Game 博弈论 nim积 sg函数

    http://poj.org/problem?id=3533 变成三维的nim积..前面hdu那个算二维nim积的题的函数都不用改,多nim积一次就过了...longlong似乎不必要但是还是加上了 ...

  7. 【20181027T2】易水决【贪心+堆】

    原题:loj6035 [错解] 全肝T1了没怎么想 [正解] 一眼贪心 先考虑\(b_i=0\)怎么做 可以模拟一个正常人的思维 开一个堆,记录每个任务需要的时间(包括等待),每次从中取出一个任务,表 ...

  8. java爬虫爬取资源,小白必须会的入门代码块

    java作为目前最火的语言之一,他的实用性也在被无数的java语言爱好者逐渐的开发,目前比较流行的爬取资源,用java来做也更简单一些,下面是爬取网页上所有手机型号,参数等极为简便的数据 packag ...

  9. 【洛谷】P1063 能量项链【区间DP】

    P1063 能量项链 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子, ...

  10. hdu 3294 manacher 求回文串

    感谢: http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/ O(n)求给定字符串的以每个位置为中心的回文串长度. 中心思想:每次计算位 ...