Node.js躬行记(25)——Web自动化测试

简介: Node.js躬行记(25)——Web自动化测试

 网页在提测流转给 QA 后,如何能帮他们更有效而准确的完成测试,是我一直在思考的一个问题。

  QA 他们会对网页编写测试用例,在提测之前会让我们将优先级最高的用例跑通,这在一定程度上能够避免频繁的返工,保证测试的顺畅。

  自己之前想过做 UI 的单元测试,一有修改就跑一遍用例,但是维护成本太高,并且每次留给我们的开发时间并不多。

  最近在看多份测试记录的 BUG 单中发现,45%~70% 之间的 BUG 都是内容性问题,例如网页中缺了个字、少了段话、图片呈现不对等问题。

  这些用肉眼看,其实很容易辨别。只要有个工具,能呈现不同操作下的网页,就可以大大提升 QA 的验收效率。

  于是就想到了 Puppeteer(傀儡师),它是一个 Node.js 库,提供了一套 API 控制 Chrome 或 Chromium 浏览器,可生成页面快照截图、模拟用户行为等。

  Chromium 是 Chrome 的开源版本,两者在界面、功能等方面会存在些区别。

  虽然 Puppeteer 可以模拟用户行为,但是它不能模拟用户在客户端 WebView 中的行为,例如点击头像进入用户客户端中的主页。

  简单理解,就是 Puppeteer 能呈现 Chrome 浏览器中的页面,但如果要测试客户端的样式兼容性和各种交互行为,就无法实现了。

  而内容展示异常的问题,无论是在哪一端,都能表现一致,因此可以用 Puppeteer 来作为自动化测试工具。


一、服务端实现


  当前 Puppeteer 的最新版本是 19.2.2,API 分为 20 多个模块,可查找页面 DOM 元素、屏幕截图、处理 WebSocket、模拟移动端设备、植入脚本、请求拦截等操作。

  我当前的目标是查看页面内容,所以在页面中也需要有些交互。

  先基于 KOA,快速搭建一个新项目,因为 Puppeteer 库比较大,所以为了不影响其他项目的构建和运行,就单独开了个项目。

  再引入相关的 Node 库,fs 用于创建目录,path 用于拼接绝对路径,config 用于读取配置文件。

const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');
const config = require('config');
const domain = config.get('domain');

  接着是声明一条路由,例如用 get 方法访问 test/game,传递类型和环境。

router.get("/test/game", async (ctx) => {
  const { type, env = "www" } = ctx.query;
  let data = [];
  switch (type) {
    case "1":
      data = await hot(env);
      break;
  }
  ctx.body = { code: 0, data };
});

  hot() 函数就是自动化测试的主体,核心逻辑其实就是点击某一栏,呈现页面后,再截一张图。

async function hot(env) {
  const savePath = path.resolve(__dirname, "../static/hot"); // 将相对路径转换成绝对路径
  const iPhone = puppeteer.KnownDevices["iPhone 6"]; // 模拟iPhone 6
  // 当指定目录不存在时,就将其创建,Sync 后缀表示同步,recursive 参数表示递归创建
  !fs.existsSync(savePath) && fs.mkdirSync(savePath, { recursive: true });
  // 要返回的图片路径
  const paths = [];
  /**
   * 本地环境可以不需要配置 args
   * 但是在 Linux 服务器中在启动 puppeteer 时,默认要带上 --no-sandbox 参数
   */
  return puppeteer.launch({
      args: ["--no-sandbox", "--disable-setuid-sandbox"]
    }).then(async (browser) => {
      const page = await browser.newPage(); // 创建新的浏览器上下文
      await page.emulate(iPhone); // 模拟设备
      // 默认主页
      await page.goto(`https://${env}.xxx.com/game/hot.html`, {
        waitUntil: "networkidle0" // 等待到没有网络请求
      });
      // 截图
      await screenshot(page, `${savePath}/1.png`);
      paths.push(`${domain}/static/hot/1.png`);
      // 查找符合样式的菜单栏
      const tabs = await page.$$(".green_calss");
      // 点击第二个菜单栏
      tabs[1].tap();
      await page.waitForNetworkIdle();
      await screenshot(page, `${savePath}/2.png`);
      paths.push(`${domain}/static/hot/2.png`);
      // 点击第三个菜单栏
      tabs[2].tap();
      await page.waitForNetworkIdle();
      await screenshot(page, `${savePath}/3.png`);
      paths.push(`${domain}/static/hot/3.png`);
      await page.close();
      await browser.close();
      return paths;
    });
}

  path.resolve()、fs.existsSync() 和 fs.mkdirSync() 都是 Node.js 提供的方法

  page.goto() 可跳转到指定 URL 的网页,networkidle0 可等待到页面无网络请求。

  在自动化测试时,需要有个页面完成的时间点,如果用延时的方式,会不太准确,所以就想到了网络请求。

  我们这边的网页以移动端居多,所以需要选择要模拟的设备,例如 iPhone 6。

  page.$$() 是 ElementHandle 提供的一个方法,相当于 Document.querySelectorAll() 方法。

  tabs[1].tap() 就是模拟用户触摸屏幕,另外支持的事件还包括 click()、drag()、focus() 等。

  screenshot() 是一个截屏函数,内部调用 page.screenshot() 方法,可截取完整页面,包括滚动区域。

async function screenshot(page, savePath) {
  await page.screenshot({
    path: savePath,
    type: "png",
    fullPage: true //边滚动边截图
  });
}


二、界面实现


  前端界面目前比较简洁,就一个活动下拉框和一个环境下拉框,以及一个提交按钮。

  提交后,就会从后台拿到页面快照,这些快照都会按照写好的脚本生成。

  

1)遇到的问题

  在实际使用中注意到,如果页面内包含一块定高区域,那么隐藏区域就需要滚动后才能呈现。

  当网页中有一个资源阻塞加载时,若是 waitUntil 参数的值是 networkidle0,那页面就会报超时的错误。

await page.goto(url, {
  waitUntil: ["networkidle0"]
});

  但如果 goto() 方法不加等待时机,那就会一直等下去,没有结果。

await page.goto(url);

  可以改成 networkidle2,networkidle0 是指在 500ms 内没有任何网络连接,而 networkidle2 是指网络连接个数不超过 2 个。

  在部署到服务器后,由于字体的问题,页面内的中文会出现乱码,解决办法就是给服务器安装中文字体。

  

 

 

参考资料:

Automating Google Chrome with Node.js

京喜前端自动化测试之路

深入了解自动化:那些项目适合自动化测试

Puppeteer中文

Puppeteer 入门教程

相关文章
|
25天前
|
安全 测试技术 网络安全
如何在Python Web开发中进行安全测试?
如何在Python Web开发中进行安全测试?
|
25天前
|
安全 关系型数据库 测试技术
学习Python Web开发的安全测试需要具备哪些知识?
学习Python Web开发的安全测试需要具备哪些知识?
32 4
|
6天前
|
Web App开发 IDE JavaScript
Selenium IDE:Web自动化测试的得力助手
Selenium IDE:Web自动化测试的利器。作为开源工具,Selenium IDE支持录制与回放用户操作,适用于Chrome、Firefox等多浏览器,简化了测试流程,提升了效率,降低了自动化测试的门槛。它还支持导出多种编程语言的脚本,便于测试集成与复用。
50 19
Selenium IDE:Web自动化测试的得力助手
|
8天前
|
Web App开发 IDE 测试技术
Selenium:强大的 Web 自动化测试工具
Selenium 是一款强大的 Web 自动化测试工具,包括 Selenium IDE、WebDriver 和 Grid 三大组件,支持多种编程语言和跨平台操作。它能有效提高测试效率,解决跨浏览器兼容性问题,进行性能测试和数据驱动测试,尽管存在学习曲线较陡、不稳定等缺点,但其优势明显,是自动化测试领域的首选工具。
79 17
Selenium:强大的 Web 自动化测试工具
|
19天前
|
JavaScript
使用Node.js创建一个简单的Web服务器
使用Node.js创建一个简单的Web服务器
|
23天前
|
机器学习/深度学习 人工智能 JavaScript
JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景
本文探讨了JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景。JavaScript将注重性能优化、跨平台开发、AI融合及WebAssembly整合;TypeScript则强调与框架整合、强类型检查、前端工程化及WebAssembly的深度结合。两者结合发展,特别是在Vue 3.0中完全采用TypeScript编写,预示着未来的Web开发将更加高效、可靠。
37 4
|
23天前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
35 2
|
25天前
|
监控 安全 测试技术
如何在实际项目中应用Python Web开发的安全测试知识?
如何在实际项目中应用Python Web开发的安全测试知识?
28 4
|
1月前
|
数据采集 存储 监控
实现自动化数据抓取:使用Node.js操控鼠标点击与位置坐标
本文介绍了如何使用Node.js和Puppeteer实现自动化数据抓取,特别是针对新闻网站“澎湃新闻”。通过设置代理IP、User-Agent和Cookie,提高爬虫的效率和隐蔽性,避免被网站封锁。代码示例展示了如何模拟鼠标点击、键盘输入等操作,抓取并整理新闻数据,适用于需要规避IP限制和突破频率限制的场景。
83 10
|
1月前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。