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

bash 复制代码
brew install go

安装ChromeDP

bash 复制代码
go get -u github.com/chromedp/chromedp

4.编写代码

示例测试

打开GoLand,新建main.go文件

main.go-核心测试

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

Go 复制代码
package main

import (
   "context"
   "fmt"
   "github.com/chromedp/chromedp"
   "github.com/chromedp/chromedp/kb"
   "log"
   "strings"
   "time"
)

func main() {
   opts := chromedp.DefaultExecAllocatorOptions[:]
   opts = append(opts,
      // Disable headless mode
      chromedp.Flag("headless", false),
      // Enable GPU (optional)
      chromedp.Flag("disable-gpu", false),
      // Start with a maximized window
      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 string
   err := 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. 检查空查询是否会导致没有搜索结果
Go 复制代码
package main

import (
   "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 string
   err := 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 string
   err := chromedp.Run(ctx,
      chromedp.Navigate("https://www.google.com"),
      chromedp.WaitVisible(`//textarea[@name="q"]`),
      chromedp.SendKeys(`//textarea[@name="q"]`, ""), // Empty query
      chromedp.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放在同一目录,然后执行命令

bash 复制代码
go test -v

测试结果

相关推荐
chen_ever1 小时前
golang之go modules
开发语言·后端·golang
今天头发还在吗3 小时前
【Go】:mac 环境下GoFrame安装开发工具 gf-cli——gf_darwin_arm64
macos·golang·go·gf-cli
是誰萆微了承諾9 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
ifanatic14 小时前
[每周一更]-(第159期):Go 工程师视角:容器化技术(Docker/Kubernetes)与CI/CD流程的应用场景
docker·golang·kubernetes
张烫麻辣亮。15 小时前
golang-gin包
开发语言·golang·gin
Sally璐璐15 小时前
Go正则表达式实战指南
数据库·mysql·golang
yuluo_YX15 小时前
Go Style 代码风格规范
开发语言·后端·golang
qq_1728055917 小时前
Go 自建库的使用教程与测试
开发语言·后端·golang
007php00720 小时前
某大厂MySQL面试之SQL注入触点发现与SQLMap测试
数据库·python·sql·mysql·面试·职场和发展·golang
雨中散步撒哈拉21 小时前
13、做中学 | 初一下期 Golang数组与切片
开发语言·后端·golang