当前位置: 首页 > news >正文

Go+chromedp实现Web UI自动化测试

1.为什么使用go进行UI自动化测试?

速度:Go速度很快,这在运行包含数百个UI测试的测试套件时是一个巨大的优势

并发性:可以利用Go的内置并发性(goroutines)来并行化测试执行

简单:Go的简约语法允许您编写可读且可维护的测试脚本

ChromeDP:一个无头Chrome/Chromium库,允许直接从Go控制浏览器

2.什么是chromedp?

ChromeDP 是一个 Go 库,允许开发者通过 Chrome DevTools 协议控制 Chrome/Chromium。借助 ChromeDP,您可以与网页交互、模拟用户输入、浏览浏览器以及提取内容进行验证。它既可以在无头模式(没有浏览器UI)下工作,也可以在有头模式(有可见浏览器)下工作。

3.设置环境

安装go

brew install go

安装ChromeDP

go get -u github.com/chromedp/chromedp

4.编写代码

示例测试

打开GoLand,新建main.go文件

main.go-核心测试

这段代码将会打开Chrome,导航到Google搜索页,搜索"Golang",并验证Golang是否出现在搜索结果中

package mainimport ("context""fmt""github.com/chromedp/chromedp""github.com/chromedp/chromedp/kb""log""strings""time"
)func main() {opts := chromedp.DefaultExecAllocatorOptions[:]opts = append(opts,// Disable headless modechromedp.Flag("headless", false),// Enable GPU (optional)chromedp.Flag("disable-gpu", false),// Start with a maximized windowchromedp.Flag("start-maximized", true),)allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)defer cancel()ctx, cancel := chromedp.NewContext(allocCtx)defer cancel()ctx, cancel = context.WithTimeout(ctx, 15*time.Second)defer cancel()var result stringerr := chromedp.Run(ctx,chromedp.Navigate("https://www.google.com"),chromedp.WaitVisible(`//textarea[@name="q"]`),chromedp.SendKeys(`//textarea[@name="q"]`, "Golang"),chromedp.SendKeys(`//textarea[@name="q"]`, kb.Enter),chromedp.WaitVisible(`#search`),chromedp.Text(`#search`, &result),)if err != nil {log.Fatal(err)}if strings.Contains(result, "Golang") {fmt.Println("Test Passed: 'Golang' found in search results")} else {fmt.Println("Test Failed: 'Golang' not found in search results")}
}

Go测试框架编写多个UI测试

新建main_test.go文件

main_test.go-多种测试结果

测试用例:

  1. 检查搜索结果是否包含术语“Golang”
  2. 验证搜索栏是否在 Google 主页上可见
  3. 检查空查询是否会导致没有搜索结果
package mainimport ("context""github.com/chromedp/chromedp""github.com/chromedp/chromedp/kb""strings""testing""time"
)// checks that the search results contain "Golang"
func TestGoogleSearch_Golang(t *testing.T) {opts := chromedp.DefaultExecAllocatorOptions[:]opts = append(opts,chromedp.Flag("headless", false),chromedp.Flag("disable-gpu", false),chromedp.Flag("start-maximized", true),)allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)defer cancel()ctx, cancel := chromedp.NewContext(allocCtx)defer cancel()ctx, cancel = context.WithTimeout(ctx, 15*time.Second)defer cancel()var result stringerr := chromedp.Run(ctx,chromedp.Navigate("https://www.google.com"),chromedp.WaitVisible(`//textarea[@name="q"]`),chromedp.SendKeys(`//textarea[@name="q"]`, "Golang"),chromedp.SendKeys(`//textarea[@name="q"]`, kb.Enter),chromedp.WaitVisible(`#search`),chromedp.Text(`#search`, &result),)if err != nil {t.Fatalf("Test Failed: %v", err)}if strings.Contains(result, "Golang") {t.Log("Test Passed: 'Golang' found in search results")} else {t.Errorf("Test Failed: 'Golang' not found in search results")}
}// checks that the search bar is visible
func TestGoogleSearch_SearchBarVisible(t *testing.T) {opts := chromedp.DefaultExecAllocatorOptions[:]opts = append(opts,chromedp.Flag("headless", false),chromedp.Flag("disable-gpu", false),chromedp.Flag("start-maximized", true),)allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)defer cancel()ctx, cancel := chromedp.NewContext(allocCtx)defer cancel()ctx, cancel = context.WithTimeout(ctx, 15*time.Second)defer cancel()err := chromedp.Run(ctx,chromedp.Navigate("https://www.google.com"),chromedp.WaitVisible(`//textarea[@name="q"]`),)if err != nil {t.Errorf("Test Failed: Search bar not visible - %v", err)} else {t.Log("Test Passed: Search bar is visible")}
}// checks if there are results when the search query is empty
func TestGoogleSearch_EmptyQuery(t *testing.T) {opts := chromedp.DefaultExecAllocatorOptions[:]opts = append(opts,chromedp.Flag("headless", false),chromedp.Flag("disable-gpu", false),chromedp.Flag("start-maximized", true),)allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)defer cancel()ctx, cancel := chromedp.NewContext(allocCtx)defer cancel()ctx, cancel = context.WithTimeout(ctx, 15*time.Second)defer cancel()var result stringerr := chromedp.Run(ctx,chromedp.Navigate("https://www.google.com"),chromedp.WaitVisible(`//textarea[@name="q"]`),chromedp.SendKeys(`//textarea[@name="q"]`, ""), // Empty querychromedp.SendKeys(`//textarea[@name="q"]`, kb.Enter),chromedp.WaitVisible(`#search`, chromedp.ByID),chromedp.Text(`#search`, &result),)if err != nil {t.Fatalf("Test Failed: %v", err)}if result == "" {t.Log("Test Passed: No search results for empty query")} else {t.Errorf("Test Failed: Unexpected results for empty query")}
}

执行测试

将main.go和main_test.go放在同一目录,然后执行命令

go test -v

测试结果

相关文章:

Go+chromedp实现Web UI自动化测试

1.为什么使用go进行UI自动化测试? 速度:Go速度很快,这在运行包含数百个UI测试的测试套件时是一个巨大的优势 并发性:可以利用Go的内置并发性(goroutines)来并行化测试执行 简单:Go的简约语法允许您编写可读且可维护…...

【MySQL 高级特性与性能优化】

MySQL 高级特性与性能优化 一、MySQL 存储引擎 (一)InnoDB 存储引擎 1. 特点 支持事务:InnoDB 是 MySQL 中提供完整 ACID 事务支持的存储引擎,这意味着它能够保证数据库操作在复杂的并发环境下的一致性、隔离性、原子性和持久…...

Spring Boot教程之三十九: 使用 Maven 将 Spring Boot 应用程序 Docker 化

如何使用 Maven 将 Spring Boot 应用程序 Docker 化? Docker是一个开源容器化工具,用于在隔离环境中构建、运行和管理应用程序。它方便开发人员捆绑其软件、库和配置文件。Docker 有助于将一个容器与另一个容器隔离。在本文中,为了将Spring B…...

微信小程序开发示例

微信小程序开发涉及多个方面&#xff0c;包括页面布局、交互逻辑、数据处理等。以下是一个简单的微信小程序开发示例&#xff0c;包括页面布局、样式定义、交互逻辑等方面的内容。 一、页面布局&#xff08;WXML&#xff09; <!-- index.wxml --> <view class"…...

【机器学习】概述

文章目录 1. 机器学习三步骤2. 机器学习图谱2.1 任务类型 (Task)2.2 模型选择 (Methods)2.3 学习场景 (Scenario) 1. 机器学习三步骤 定义一个模型 (Define a set of function) 选择一组合适的函数来表示模型。 评估模型好坏 (Goodness of function) 找到一个损失函数&#xf…...

音视频采集推流时间戳记录方案

音视频同步更多文章 深入理解音视频pts&#xff0c;dts&#xff0c;time_base以及时间数学公式_视频pts计算-CSDN博客 ffplay音视频同步分析_ffplay 音视频同步-CSDN博客 音视频采集打时间戳设计 实时音视频数据的采集和处理场景。具体来说: 采集阶段: 在音视频数据采集过…...

【Linux】:线程安全 + 死锁问题

&#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;Linux—登神长阶 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f49e; &#x1f49e; &#x1f49e; 1. 线程安全和重入问题&…...

【深度学习】时间序列表示方法

自然界除了2D的图片数据之外&#xff0c;还有语音、文字&#xff0c;这些数据都有时间的先后顺序的。对于2D的图像的数据&#xff0c;可以用RGB值来表示像素的色彩度。语音可以用信号幅度值来表示&#xff0c;而Pytorch没有自带String支持&#xff0c;在表示文字之前需要进行Em…...

1.微服务灰度发布落地实践(方案设计)

文章目录 前言灰度发布的优点设计概要系统架构图流量控制客户端服务端 路由路径应用客户端实现核心组件分析1.网关2. spring-cloud3. dubbo4. nocas5. thread6. message queue 前言 微服务架构中的灰度发布&#xff08;也称为金丝雀发布或渐进式发布&#xff09;是一种在不影响…...

【UE5 C++课程系列笔记】15——Assert的基本使用

目录 概念 一、Check 二、Verify 三、Ensure 对比 基本使用 一、check的基本使用 二、ensure的基本使用 三、verify的基本使用 概念 assert 可在开发期间帮助检测和诊断不正常或无效的运行时条件。这些条件通常检查是否指针为非空、除数为非零、函数并非递归运行&…...

kubernetes Gateway API-1-部署和基础配置

文章目录 1 部署2 最简单的 Gateway3 基于主机名和请求头4 重定向 Redirects4.1 HTTP-to-HTTPS 重定向4.2 路径重定向4.2.1 ReplaceFullPath 替换完整路径4.2.2 ReplacePrefixMatch 替换路径前缀5 重写 Rewrites5.1 重写 主机名5.2 重写 路径5.2.1 重新完整路径5.2.1 重新部分路…...

likeAdmin架构部署(踩坑后的部署流程

1、gitee下载 https://gitee.com/likeadmin/likeadmin_java.git 自己克隆 2、项目注意 Maven&#xff1a;>3.8 ❤️.9 (最好不要3.9已经试过失败 node &#xff1a;node14 (不能是18 已经测试过包打不上去使用14的换源即可 JDK&#xff1a;JDK8 node 需要换源 npm c…...

【一款超好用的开源笔记Logseq本地Docker部署与远程使用指南】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

浅谈torch.utils.data.TensorDataset和torch.utils.data.DataLoader

1.torch.utils.data.TensorDataset 功能定位 torch.utils.data.TensorDataset 是一个将多个张量&#xff08;Tensor&#xff09;数据进行简单包装整合的数据集类&#xff0c;它主要的作用是将相关联的数据&#xff08;比如特征数据和对应的标签数据等&#xff09;组合在一起&…...

gesp(C++二级)(16)洛谷:B4037:[GESP202409 二级] 小杨的 N 字矩阵

gesp(C++二级)(16)洛谷:B4037:[GESP202409 二级] 小杨的 N 字矩阵 题目描述 小杨想要构造一个 m m m \times m m...

FFmpeg:详细安装教程与环境配置指南

FFmpeg 部署完整教程 在本篇博客中&#xff0c;我们将详细介绍如何下载并安装 FFmpeg&#xff0c;并将其添加到系统的环境变量中&#xff0c;以便在终端或命令行工具中直接调用。无论你是新手还是有一定基础的用户&#xff0c;这篇教程都能帮助你轻松完成 FFmpeg 的部署。 一、…...

《特征工程:自动化浪潮下的坚守与变革》

在机器学习的广阔天地中&#xff0c;特征工程一直占据着举足轻重的地位。它宛如一位幕后的工匠&#xff0c;精心雕琢着原始数据&#xff0c;将其转化为能够被机器学习模型高效利用的特征&#xff0c;从而推动模型性能迈向新的高度。然而&#xff0c;随着技术的飞速发展&#xf…...

webrtc 源码阅读 make_ref_counted模板函数用法

目录 1. 模板参数解析 1.1 typename T 1.2 typename... Args 1.3 typename std::enable_if::value, T>::type* nullptr 2. scoped_refptr 3. new RefCountedObject(std::forward(args)...); 4. 综合说明 5.在webrtc中的用法 5.1 peerConnectionFactory对象的构建过…...

【深度学习基础之多尺度特征提取】特征金字塔(Feature Pyramid)是如何在深度学习网络中提取多尺度特征的?附代码

【深度学习基础之多尺度特征提取】特征金字塔&#xff08;Feature Pyramid&#xff09;是如何在深度学习网络中提取多尺度特征的&#xff1f;附代码 【深度学习基础之多尺度特征提取】特征金字塔&#xff08;Feature Pyramid&#xff09;是如何在深度学习网络中提取多尺度特征…...

【Docker】离线安装 Docker

离线安装 Docker 在CentOS系统上安装Docker 1、下载 Docker 仓库文件 https://download.docker.com/linux/centos/docker-ce.repo 2、添加 Docker 仓库文件 将上一步下载的文件&#xff0c;移动到 /etc/yum.repos.d/ 目录 3、清除 YUM 缓存 sudo yum clean all sudo yum…...

Qt for Android串口通信实战:usb-serial-for-android库的完整集成指南

Qt for Android串口通信实战&#xff1a;usb-serial-for-android库的完整集成指南 在工业控制、物联网设备调试等场景中&#xff0c;串口通信仍然是设备间可靠数据传输的首选方案。当我们需要在Android设备上通过Qt框架实现串口通信时&#xff0c;却发现Qt官方并未提供原生的A…...

数据结构八股(一)

参考这个&#xff1a;https://blog.csdn.net/weixin_52341045/article/details/134395797?fromshareblogdetail&sharetypeblogdetail&sharerId134395797&sharereferPC&sharesource2401_82607598&sharefromfrom_link 链表&#xff0c;队列和栈的区别 链表…...

利用快马AI快速原型:十分钟搭建你的简易版图拉丁工具箱

最近在折腾硬件检测工具&#xff0c;想做个类似图拉丁吧工具箱的简易版。作为一个懒人开发者&#xff0c;我尝试用InsCode(快马)平台来快速实现原型验证&#xff0c;结果十分钟就搞定了核心功能。分享一下这个快速开发过程&#xff1a; 需求分析 硬件检测工具最基础的功能就是获…...

[c++] STL概括

STL 是 C 标准库的核心&#xff0c;包含容器、迭代器、算法、函数对象四大组件。对于 OI 竞赛&#xff0c;熟练掌握 STL 可以大幅减少代码量、降低调试难度&#xff0c;是提升代码效率和准确率的关键。 &#xfffc; 一、常用容器&#xff08;Container&#xff09; 1. 序列容器…...

NCM格式解密终极指南:三分钟解锁网易云音乐加密文件

NCM格式解密终极指南&#xff1a;三分钟解锁网易云音乐加密文件 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器使用而烦恼吗&#xff1f;ncmdump工具为你提供完整解决方案&#…...

Phi-4-mini-reasoning模型微调入门:使用自有数据提升领域推理能力

Phi-4-mini-reasoning模型微调入门&#xff1a;使用自有数据提升领域推理能力 1. 为什么需要微调推理模型 在实际业务场景中&#xff0c;通用大模型虽然具备强大的推理能力&#xff0c;但在特定领域的表现往往不尽如人意。比如在法律条文解读或医疗诊断建议这类专业领域&…...

GPT-6,曝光了,当 AGI 只剩最后一公里,我们为何仍把 GPU 当燃料?

“土豆”熟了&#xff0c;代号 GPT-6。过去两周&#xff0c;OpenAI 的保密墙像被筛子砸过&#xff0c;4 月 14 日这个日期在内部聊天频道被反复 全员。知情人士说&#xff0c;那天的发布按钮其实已经提前写好&#xff0c;只等 Brockman 一声令下。为什么如此急迫&#xff1f;因…...

SenseVoice Small开发者调试指南:日志输出、错误定位与修复路径

SenseVoice Small开发者调试指南&#xff1a;日志输出、错误定位与修复路径 1. 项目背景与核心价值 SenseVoice Small是阿里通义千问推出的轻量级语音识别模型&#xff0c;专门针对移动端和边缘计算场景优化。我们在实际部署中发现&#xff0c;虽然模型本身非常优秀&#xff…...

实战应用:基于快马平台将openclaw部署到工业零件分拣场景

在工业自动化领域&#xff0c;零件分拣一直是个既基础又关键的环节。最近我在一个项目中尝试用openclaw算法来解决传送带上混合零件中特定型号螺丝的识别与抓取问题&#xff0c;整个过程既有挑战也有不少收获&#xff0c;今天就来分享一下实战经验。 场景需求分析 传送带上的螺…...

python基于智能推荐算法的全屋定制平台网站设计_07y1pcxm

前言随着人们对家居环境品质的追求不断提高&#xff0c;全屋定制平台应运而生。本文介绍的基于智能推荐算法的全屋定制平台网站设计&#xff0c;旨在为用户提供一站式的家居定制解决方案。采用 Python 语言结合 Django 框架进行开发&#xff0c;以 MySQL 数据库作为数据存储核心…...