在 UI 自动化中调用浏览器 API 的方法与使用场景

事情的背景是最近在新项目中做 UI 自动化, 就想调研一下如何与浏览器的 API 交互获取一些额外的信息以在 case 失败的时候获取一些额外的信息帮助 debug。 后来就又慢慢延伸到了前端性能测试,弱网测试等场景上去了。 所以把调研的结果记录在这里。 主要是为了解决以下的问题:

  • 测试的时候总会遇到一些偶发的 bug,发现自动化 case 失败以后再去页面上操作也很难复现。 所以如果能拿到失败的时候页面里所有请求的 request 和 response 有利于排查问题。 相当于调用了 chrome devtools 的 network 功能。
  • 测试的时候总能遇到页面元素加载的比较慢导致 case 失败的。 所以如果能获取页面上每一个资源, 包括 js, 图片, css 等文件以及网络请求的时间数据, 也是能帮助排查问题的。
  • 在 UI 自动化测试中引入前端性能测试的需求, 计算页面的一些关键指标, 比如 TTFB。

获取性能信息

获取性能信息的方法依赖于浏览器的 API, 不过好在目前这个 API 已经形成标准了。 我们打开浏览器的控制台, 就可以自己去编写 js 代码来调用这个 API。 api 有两个, 分别是 performance.timing 和 performance.getEntriesByType. 我们先说第一个接口, 当我们在控制台输入 js 代码后, 就会出现如下的信息:

performance.timing 接口是获取当前页面的各项性能数据。 这其中每个字段的含义如下:

navigationStart:浏览器处理当前网页的启动时间

fetchStart:浏览器发起http请求读取文档的毫秒时间戳。

domainLookupStart:域名查询开始时的时间戳。

domainLookupEnd:域名查询结束时的时间戳。

connectStart:http请求开始向服务器发送的时间戳。

connectEnd:浏览器与服务器连接建立(握手和认证过程结束)的毫秒时间戳。

requestStart:浏览器向服务器发出http请求时的时间戳。或者开始读取本地缓存时。

responseStart:浏览器从服务器(或读取本地缓存)收到第一个字节时的时间戳。

responseEnd:浏览器从服务器收到最后一个字节时的毫秒时间戳。

domLoading:浏览器开始解析网页DOM结构的时间。

domInteractive:网页dom树创建完成,开始加载内嵌资源的时间。

domContentLoadedEventStart:网页DOMContentLoaded事件发生时的时间戳。

domContentLoadedEventEnd:网页所有需要执行的脚本执行完成时的时间,domReady的时间。

domComplete:网页dom结构生成时的时间戳。

loadEventStart:当前网页load事件的回调函数开始执行的时间戳。

loadEventEnd:当前网页load事件的回调函数结束运行时的时间戳。

根据上面给出的信息,我们就可以计算出当前页面相关的性能指标。 比如想计算 TTFB(浏览器处理当前网页的启动时间到接收到服务器的第一个 byte 的时间)的话就是 responseStart - navigationStart 。 先发一下目前我统计的指标:

navigation_start = browser.driver.execute_script("return window.performance.timing.navigationStart")
response_start = browser.driver.execute_script("return window.performance.timing.responseStart")
dom_complete = browser.driver.execute_script("return window.performance.timing.loadEventEnd")

# 开始计算页面性能
backend_performance_calc = response_start - navigation_start  # TTFB(前端从服务端收到第一个字节的时间,也有人称白屏时间)
frontend_performance_calc = dom_complete - response_start  # 前端加载页面时间
dns_duration = browser.driver.execute_script(
    "return (window.performance.timing.domainLookupEnd - window.performance.timing.domainLookupStart)")  # DNS查询时间
tcp_duration = browser.driver.execute_script(
    "return (window.performance.timing.connectEnd - window.performance.timing.connectStart)")  # TCP连接时间

logger.info('当前页面: {url}'.format(url=browser.driver.current_url))
logger.info("TTFB(前端从服务端收到第一个字节的时间): %s 毫秒" % backend_performance_calc)
logger.info("前端加载时间(从服务到收到第一个字节到domComplete的时间): %s 毫秒" % frontend_performance_calc)
logger.info("DNS查询时间: %s 毫秒" % dns_duration)
logger.info("tcp连接时间: %s 毫秒" % tcp_duration)

当然这种计算方法是有缺陷的。 因为现在的前端项目都是 event loop, 资源都是异步加载的。 而浏览器现在也都会为同一个域名开 6 个 TCP 链接并发处理。 所以上面的计算 TTFB 的方式只是页面开始渲染的时间。 但是针对没一个 JS, CSS, 图片和网络请求来说我们仍然需要单独计算他们的性能。 所以这里需要用到第二个 APIperformance.getEntriesByType 或者 performance.getEntries。 如下图:

这个 API 会抓取到浏览器与服务交互的每一个请求的性能信息。 所以代码编写如下:

responses = browser.driver.execute_script("return performance.getEntriesByType('resource')")
for r in responses:
    logger.info(
        "资源名称:{name}, 耗时:{duration}毫秒, 传输大小字节数:{transferSize}, encodedBodySize:{encodedBodySize}".format(
            name=r['name'], duration=str(r['duration']),
            transferSize=str(r['transferSiz
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酔清风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值