11月阅读周·编写可测试的JavaScript代码:性能测试之生成HAR文件篇
背景
去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。
没有计划的阅读,收效甚微。
新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。
这个“玩法”虽然常见且板正,但是有效,已经坚持阅读十个月。
已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》、《WebKit技术内幕》、《前端架构:从入门到微前端》、《秒懂算法:用常识解读数据结构与算法》、《JavaScript权威指南》、《JavaScript异步编程设计快速响应的网络应用》。
当前阅读周书籍:《编写可测试的JavaScript代码》。
生成HAR文件
有几个工具可以生成HAR文件。最灵活的是一个可编程的代理,其拦截HTTP请求和响应。该代理可以使用包括手机在内的任何浏览器,为其提供最大的灵活性。
另一个选择是使用像tcpdump(https://www.tcpdump.org/)这样的封装嗅探工具,以PCAP格式来捕获HTTP流量,然后使用像pcap2har(https://github.com/andrewf/pcap2har/)这样的工具生成HAR。这可以说是给出了“真实”的性能数据,因为在服务器和客户端之间没有代理服务器。虽然这种方法有点乱,但如果代理方式不能用的话,我鼓励大家尝试一下这种方式。例如,移动浏览器不允许设置代理,所以要生成HAR文件就需要一个嗅探工具。
使用代理
要研究代理是如何工作的,我们试用一下开源编程代理browsermob(https://github.com/webmetrics/browsermob-proxy)。该代理使用Java编写,很容易集成到Selenium WebDriver脚本,并且拥有一些很不错的可编程特性,以及一个REST接口。
使用browsermob,只需启动代理,就可以开始捕获HAR了,启动Selenium WebDriver,并设置browsermob代理,使用Selenium连接并进行任意处理操作,然后从browsermob中收集HAR并转储到一个文件中。
browsermob默认在端口8080上启动。这不是一个代理端口,而是REST接口通信的端口,所以没有理由去改变它,但可以改变它。
下载browsermob-proxy之后,开始安装:
/bin/sh bin/browsermob-proxy
现在可以用它来启动和卸载一个(或多个)代理,也可以利用它的其他功能。我编写了browsermob-proxy的JavaScript绑定,可通过npm包获取:
npm install browsermob-proxy
此时,就可以使用JavaScript生成一些相关的HAR文件了!
首先,HAR文件只能使用Selenium WebDriver在Firefox或Internet Explorer下自动生成,因为只有这些浏览器的代理设置可以被Selenium WebDriver以编程的方式进行修改。因为HAR要测量网络时间,这不是什么大问题,除非每个浏览器请求的发布资源完全不同。这意味着,必须在某个地方运行Selenium服务器以启动Firefox或Internet Explorer(独立或网格)。
browsermob-proxy npm模块将使用如下两种方法中的一种进行HAR的生成:
- 简单方法
- 高级方法
让我们先从简单的方法开始,如果只有一个URL并想查看其瀑布图,则建议使用该方法。如下代码生成了Yahoo.com的HAR文件。
var proxy = require('browsermob-proxy').proxy,
fs = require('fs'),
proxy = new proxy();
proxy.dohar('http://yahoo.com', function (err, data) {
if (err) {
console.error('error: ' + err);
} else {
fs.writefilesync('yahoo.com.har', data, 'utf8');
}
});
在上述代码中,我们加载了browsermob-proxy模块,并创建了一个新的Proxy对象。该对象没有参数,它假定browsermob-proxy是在localhost或端口8080上运行。接下来,直接传入URL和回调,如果没有错误,回调的第二个参数就是该站点的HAR数据。将这些数据转储到一个文件,工作就完成了。
如果browsermob-proxy不是在localhost或端口8080(默认值)上运行,在构造函数中指定即可:
proxy = new proxy( { host:'some.other.host', port: 9999 } )
还要记住,上述代码在某个地方需要2.x版本的Selenium服务器;默认配置假设它在本地主机的4444端口上运行。如果不是这种情况,必须要在Proxy的构造函数进行指定才行:
proxy = new proxy( { selHost:'some.other.host', selPort: 9999 } )
现在,让我们看一下生成HAR文件的高级方法。如果要为更高级的单页面Web应用程序生成HAR文件,会使用这个方法。使用该方法,需要设置代理,然后开始捕获数据,browsermob-proxy模块通过代理回调Selenium代码。接着利用代理,用任何浏览器访问任何想访问的页面,就可以实例化一个Selenium对象,然后利用我们提供的回调生成HAR文件,该回调接收了HAR数据。
对于该示例,我们将使用先前的Selenium webdriverjs示例加载一个雅虎页面,然后查找“JavaScript”。首先,为该交互的所有内容生成一个HAR文件。
该方法假设browsermob-proxy和该脚本在同一主机(localhost)和默认端口(8080)上运行。可以向Proxy传入一个配置对象修改这些值。该方法还允许我们控制Selenium交互,所以即便Selenium独立服务器或网格没有在localhost端口4444上运行,也不再需要向Proxy构造函数的selHost和selPort进行传值了。
同时,也不要忘记Selenium的动态代理注入仅适用于使用WebDriver(不是Selenium1/Remote Control)的Firefox和Internet Explorer,所以Selenium webdriverjs对象必须指定两个浏览器中的一个。
browsermob-proxy npm包还允许我们指定带宽和延迟。这不仅有助于HAR生成,还能进行降速测试,使用200毫秒的延迟,以56k调制解调器的方式体验自己的网站,就像在地球的两端拨打电话一样。使用downloadKbps、uploadKbps和latency键,可以在Proxy构造函数中指定这些值,示例如下:
proxy = new Proxy({
downloadKbps: 56,
uploadKbps: 56,
latency: 200,
});
这将导致访问速度显著下降,对于测试低带宽来说,这是很有必要的。
browsermob-proxy还允许进一步的高级交互。我强烈建议大家用一下。其他的选择,如Fiddler和Charles可以做类似的事情,但browsermob-proxy是免费的,并且用起来很好。
但是为什么只有Selenium才能做这样的事情呢?PhantomJS和CasperJS同样擅长生成HAR文件。我们需要做的只是设置代理而已,PhantomJS和CasperJS这两者都很容易做到。
browsermob-proxy模块使用Node.js编写,而PhantomJS / CasperJS则完全不同,即使它们看起来非常相似。因此,首先我们必须要使用Node.js建立代理,模拟产生一个带有正确代理信息的CasperJS,最后收集HAR并将其输出到Node.js。
基本上,除了向Selenium传递的函数回调要模拟生成CasperJS脚本进行驱动以外,该过程非常类似于我们前面使用的高级方法。一旦完成,我们就可以收集HAR。也许有一天,PhantomJS和Node.js在一起使用会非常好,或者PhantomJS可以获得HTTP请求代码。在那之前,我们还是需要Node.js。
传入Selenium函数的是带有browsermob代理设置信息的、真实模拟的CasperJS任务(即,在命令行上传递的脚本)。一旦CasperJS进程退出,我们就回调生成HAR文件。
这表明,在生成HAR文件时任何程序都可以“驱动”Web交互。在这里,我们看到了Selenium和CasperJS是如何做的,但任何其他能驱动浏览器且可以设置代理的工具也都可以做得非常好。
总结
性能测试的一个核心问题是了解Web应用程序的负载情况。HTTP存档格式(HAR)是捕获这些信息的标准;规范可以在Jan Odvarko的博客上找到。HAR是一个可用于查看的json格式对象,可以使用很多工具对其进行查看,包括免费在线查看器。要监控Web应用程序的性能,需要生成应用程序概要的HAR文件,然后检查数据并发现问题。随着时间的推移,捕获并监测这些数据,会让我们了解应用程序是如何执行的。
作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)