如何自动化获取接口请求时间的详细数据

247 篇文章 0 订阅
183 篇文章 0 订阅

2024软件测试面试刷题,这个小程序(永久刷题),靠它快速找到工作了!(刷题APP的天花板)_软件测试刷题小程序-CSDN博客文章浏览阅读2.5k次,点赞85次,收藏11次。你知不知道有这么一个软件测试面试的刷题小程序。里面包含了面试常问的软件测试基础题,web自动化测试、app自动化测试、接口测试、性能测试、自动化测试、安全测试及一些常问到的人力资源题目。最主要的是他还收集了像阿里、华为这样的大厂面试真题,还有互动交流板块……_软件测试刷题小程序https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502一、背景

  • 背景:由于内部的图片加载时间过长,后续经过压缩优化后,有效降低了前后的请求速度和图片大小,现在要收集每个图片的请求时间。
  • 整体思路:采用浏览器自动化运行访问并收集数据

二、方案

  • 采用Performance API进行收集 (无法统计单个请求的时间)
  • 采用puppteer控制浏览器进行收集,通过timing API进行获取

三、开发

启动浏览器并获取接口时间

前期调研过发现puppteer无法获取content_download数据。这里采用playwright 进行操控浏览器。

首先先安装playwright ,选择不安装浏览器,我们会启动自己本地的浏览器来进行爬取。

npm init playwright@latest

先启动浏览器

const playwright = require('playwright');

const CHROME_PATH = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'; // chrome路径

// 根据用户的数据进行chrome启动
const ctx = playwright.chromium.launch({
  channel: 'chrome',
  headless: false, // 把无头模式关闭
  executablePath: CHROME_PATH, // chrome的可执行文件路径
  devtools: true,
})
// 上面的ctx就是一个浏览器实例,可以打开多个页面

// 开启了一个页面
const page = await browser.newPage();
// 跳转到对应的链接
page.goto('跳转到你的链接')

上面就已经成功启动了本地的chrome,但是会发现页面的状态是没有登录的,那可以不可以用本地的cookie呢,答案是可以的,首先要找到浏览器的cookie存放在哪,可以在 chrome://version 中看到个人资料路径就是你的数据存放地。

在playwright也是可以根据用户的数据存放地进行启动的。

const PROFILE_PATH = '~/Library/Application Support/Google/Chrome/';
// 只需要启动的时候launchPersistentContext 使用函数传递数据地址即可
const ctx= playwright.chromium.launchPersistentContext(PROFILE_PATH,{
   ...config
})

再次启动就能看到有带上用户数据了,下一步就是该去获取接口数据了,可以利用request事件进行监听,然后利用timing API进行获取时间。

page.on('request', request => {
  const log = {
    time: JSON.stringify(request.timing()),
    url: request.url(),
    // dns解析时间
    dns: request.timing().domainLookupEnd - request.timing().domainLookupStart,
    // 建立TCP链接的时间,包含SSL握手时间
    tcp: request.timing().connectEnd - request.timing().connectStart,
    // SSL握手时间
    ssl: request.timing().connectEnd - request.timing().secureConnectionStart,
    // 发出请求耗时+首个字节时间+下载耗时
    request_TTFB_download: request.timing().responseStart - request.timing().requestStart,
    // 上面的所有时间
    total: request.timing().responseEnd,
  }
  console.table(log)
})

根据上面的代码和时间就能获取到对应的阶段时间。但是实际的运行结果却是0或者-1,我们查阅文档发现为-1的时候代表该值无效。

image.png

那么可以猜测这个是请求已发出就触发了该事件,那当然没有具体的时间,我们需要等待请求完成后再进行时间的获取。


方法一:查阅文档我们发现Response中的API有finished函数可以等待完成,代码稍做改造

page.on('request', async request => {
  request.response().then(async response => {
      if(!response) return;
      await response.finished()
      // log
  })
})

方法二:可以直接使用requestfinished事件进行监听回调,requestfinished会在请求结束后触发

改造后就能成功获取时间了

image.png


下一个问题就是这个页面的图片是懒加载的,我们要等待到当前可视区域的所有的图片请求完成后,让页面往下滚动一屏幕,直到最后一个图片请求完成。那我们如何知道当前页面图片已经加载完成了呢,我们的请求都发出去了,只需要判断当前页面是否还存在未完成的请求即可,如果都完成了就开始向下翻页,直到页面最底完成最后一个请求。

首先可以通过 waitForRequest 这个API进行检查

// 先等待1s,让之前的tcp连接断开
await page.waitForTimeout(1000)
// domain 是来判断对应的域名
page.waitForRequest(request => request.url().includes(domain), { timeout });

有了判断条件接下来就是当条件满足的时候去滚动对应的页面,由于这个项目是有iframe的,需要等待iframe先加载完成。没有iframe的话直接等待对应的元素加载完成获取即可

const frame = await page.waitForSelector('iframe')

// 获取iframe的节点的元素句柄的内容框架
const frameContent = await frame.contentFrame()

接下来就是等待滚动区域

await frameContent.waitForSelector('你的选择器')

// 这里需要当前的一屏幕高度,滚动总高度,当前滚动高度
const heightInfo = await frameContent.evaluate((selector) => {
  const element = document.querySelector(selector);
  return element ? {
    scrollHeight: element.scrollHeight,
    scrollTop: element.scrollTop,
    clientHeight: element.clientHeight,
  } : null;
}, '你的选择器');

有了这些信息后只要当没有请求的时候,就让页面进行滚动就可以直到完成并打开下一页。

现在已经获取到了时间了,那么我们就需要统计数据到excel表格里面。

生成数据

由于我们需要对比前后的数据,我们将每个链接作为一个sheet,对比的时候只需要获取对应sheet的值即可,每列的数据按下面的格式通过xlsx库输出到excel即可

const log = {
    time: JSON.stringify(request.timing()),
    url: request.url(),
    // dns解析时间
    dns: request.timing().domainLookupEnd - request.timing().domainLookupStart,
    // 建立TCP链接的时间,包含SSL握手时间
    tcp: request.timing().connectEnd - request.timing().connectStart,
    // SSL握手时间
    ssl: request.timing().connectEnd - request.timing().secureConnectionStart,
    // 发出请求耗时+首个字节时间+下载耗时
    request_TTFB_download: request.timing().responseStart - request.timing().requestStart,
    // 上面的所有时间
    total: request.timing().responseEnd,
  }
  const dataList = []
  
  dataList.push(log)

初始化文件

const xlsx = require('xlsx')
const FILE_NAME = '你要的初始化文件名'

//检查文件是否存在
function checkFileExist() {
  return fs.existsSync(FILE_NAME)
}


function createFile() {
  if (!checkFileExist()) {
    const workbook = xlsx.utils.book_new();
    const worksheet = xlsx.utils.json_to_sheet([]);
    xlsx.utils.book_append_sheet(workbook, worksheet, 'sheet1');
    xlsx.writeFile(workbook, FILE_NAME);
  }
}

try {
  createFile()
} catch {
}

数据覆盖和写入

function appendFile(data, sheetName, fileName = FILE_NAME) {
  const workbook = xlsx.readFile(fileName);
  const worksheet = xlsx.utils.json_to_sheet(data);

  // 如果表里有重名的需要先删掉再覆盖
  if (workbook.Sheets[sheetName]) {
    // 删除表
    delete workbook.Sheets[sheetName];
    // 更新 SheetNames 数组
    workbook.SheetNames = workbook.SheetNames.filter(sheetNameItem => sheetNameItem !== sheetName);

    // 保存更新后的工作簿
    xlsx.writeFile(workbook, fileName, {bookType: 'xlsx'});
  }
  xlsx.utils.book_append_sheet(workbook, worksheet, sheetName);
  xlsx.writeFile(workbook, fileName)
}

总结

playwright或者puppteer可以做的事情不止这么点,我们要多发现工作中的一些重复而且繁琐的事情,让脚本代替我们完成,这样可以节省时间去干别的更加有意义的事情

行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群: 786229024,里面有各种测试开发资料和技术可以一起交流哦。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 16
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值