端对端 自动化单元测试

端对端 自动化单元测试

  1. W3C WebDriver 标准
  2. 自动化启动浏览器、开启Tab页
    1. 测试单元用例
  3. 输出结果

浏览器自动化提要

W3C WebDriver API. 标准

浏览器 OpenApi : https://www.w3.org/TR/webdriver1/#list-of-endpoints

各浏览器 OpenApi 的实现

以下为各厂家对于浏览器 OpenApi的实现

https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/

BrowserSupported OSMaintained byDownloadIssue Tracker
Chromium/ChromeWindows/macOS/LinuxGoogleDownloadsIssues
FirefoxWindows/macOS/LinuxMozillaDownloadsIssues
EdgeWindows/macOSMicrosoftDownloadsIssues
Internet ExplorerWindowsSelenium ProjectDownloadsIssues
SafarimacOS High Sierra and newerAppleBuilt inIssues

Chrome 为例

针对 不同的版本,具有不同的浏览器驱动,需要查看当前浏览器版本,再下载对应版本的驱动

如: 当前 Chrome 已是最新版本 版本 104.0.5112.101(正式版本) (arm64)

从下载地址(https://chromedriver.chromium.org/downloads)

下载对应一下版本号的的驱动即可

JS 模块 抹平各浏览的差异

JS模块是对于Api的使用且已经抹平各浏览器厂家API的差异

webdriver

https://www.npmjs.com/package/webdriver

npm i webdriver

WebdriverIO

https://www.npmjs.com/package/webdriverio

npm install webdriverio

selenium-webdriver

https://www.npmjs.com/package/selenium-webdriver

# 安装JS驱动
npm install selenium-webdriver

WebBriver 服务

本地服务

const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');

/**
 * 获取驱动服务
 * 浏览器驱动启动后,会挂载到一个端口上我们可以通过HTTP服务访问、操作浏览器
 */
const service = new chrome.ServiceBuilder('/Users/shang/Code/github/webdriver/chromedriver');
// 获取Chrome浏览器配置
const options = new chrome.Options();
// 浏览器参数设置
const arguments = [
  '--disable-web-security', // 关闭浏览器安全设置,如:浏览器跨域
  '--incognito',            // 使用隐身模式
  '--user-data-dir=/Users/shang/Downloads/chromeincognito' // 设置当前用户的工作目录
]
options.addArguments.apply(options, arguments);

(async () => {

const driver = await new Builder()
  .setChromeOptions(options)
  .forBrowser('chrome')
  .setChromeService(service)
  .build();

driver.getSession()
await driver.manage().setTimeouts({ implicit: 500 });

// 退出浏览器
// driver.quit()

})();

远端服务

启动远端服务
➜  webdriver ls
chromedriver      index.js          node_modules      package-lock.json package.json
➜  webdriver ./chromedriver
Starting ChromeDriver 104.0.5112.79 (3cf3e8c8a07d104b9e1260c910efb8f383285dc5-refs/branch-heads/5112@{#1307}) on port 9515
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.

添加IP白名单

➜  webdriver ./chromedriver --allowed-ips='0.0.0.0'
Starting ChromeDriver 104.0.5112.79 (3cf3e8c8a07d104b9e1260c910efb8f383285dc5-refs/branch-heads/5112@{#1307}) on port 9515
Remote connections are allowed by an allowlist (0.0.0.0).
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.

其他配置

➜  webdriver ./chromedriver --help
Usage: ./chromedriver [OPTIONS]

Options
  --port=PORT                     port to listen on
  --adb-port=PORT                 adb server port
  --log-path=FILE                 write server log to file instead of stderr, increases log level to INFO
  --log-level=LEVEL               set log level: ALL, DEBUG, INFO, WARNING, SEVERE, OFF
  --verbose                       log verbosely (equivalent to --log-level=ALL)
  --silent                        log nothing (equivalent to --log-level=OFF)
  --append-log                    append log file instead of rewriting
  --replayable                    (experimental) log verbosely and don't truncate long strings so that the log can be replayed.
  --version                       print the version number and exit
  --url-base                      base URL path prefix for commands, e.g. wd/url
  --readable-timestamp            add readable timestamps to log
  --enable-chrome-logs            show logs from the browser (overrides other logging options)
  --allowed-ips=LIST              comma-separated allowlist of remote IP addresses which are allowed to connect to ChromeDriver
  --allowed-origins=LIST          comma-separated allowlist of request origins which are allowed to connect to ChromeDriver. Using `*` to allow any host origin is dangerous!
调用远端服务
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');

/**
 * 获取驱动服务
 * 浏览器驱动启动后,会挂载到一个端口上我们可以通过HTTP服务访问、操作浏览器
 */
// const service = new chrome.ServiceBuilder('/Users/shang/Code/github/webdriver/chromedriver');
// 获取Chrome浏览器配置
const options = new chrome.Options();
// 浏览器参数设置
const arguments = [
  '--disable-web-security', // 关闭浏览器安全设置,如:浏览器跨域
  '--incognito',            // 使用隐身模式
  '--user-data-dir=/Users/shang/Downloads/chromeincognito' // 设置当前用户的工作目录
]
options.addArguments.apply(options, arguments);

(async () => {

const driver = await new Builder()
  .usingServer("http://127.0.0.1:9515")
  .setChromeOptions(options)
  .forBrowser('chrome')
//  .setChromeService(service)
  .build();

driver.getSession()
await driver.manage().setTimeouts({ implicit: 500 });

// 退出浏览器
// driver.quit()

})();

配置端到端准备

以 selenium-webdriver 为例

安装依赖

浏览器安装

略过,chrome , Firefox, Edge

安装浏览器驱动

根据浏览器下载驱动

Chrome 安装

下载地址: https://chromedriver.chromium.org/downloads

104 版本平台区分

Linux: https://chromedriver.storage.googleapis.com/104.0.5112.79/chromedriver_linux64.zip

Mac64: https://chromedriver.storage.googleapis.com/104.0.5112.79/chromedriver_mac64.zip

Mac64M1: https://chromedriver.storage.googleapis.com/104.0.5112.79/chromedriver_mac64_m1.zip

配置

# 创建工作目录
npm inint -y 
# 安装 selenium-webdriver ,当前为 4.4.0 版本
npm install --save-dev selenium-webdriver

示例:启动浏览器

Chrome 浏览器相关的参数,

https://blog.csdn.net/swe_ling/article/details/125811499?spm=1001.2014.3001.5502

const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');

/**
 * 获取驱动服务
 * 浏览器驱动启动后,会挂载到一个端口上我们可以通过HTTP服务访问、操作浏览器
 */
const service = new chrome.ServiceBuilder('/Users/shang/Code/github/webdriver/chromedriver');
// 获取Chrome浏览器配置
const options = new chrome.Options();
// 浏览器参数设置
const arguments = [
  '--disable-web-security', // 关闭浏览器安全设置,如:浏览器跨域
  '--incognito',            // 使用隐身模式
  '--user-data-dir=/Users/shang/Downloads/chromeincognito' // 设置当前用户的工作目录
]
options.addArguments.apply(options, arguments);

(async () => {

const driver = await new Builder()
  .setChromeOptions(options)
  .forBrowser('chrome')
  .setChromeService(service)
  .build();

driver.getSession()
await driver.manage().setTimeouts({ implicit: 500 });

// 退出浏览器
// driver.quit()

})();

功能操作

打开浏览器

打开浏览器或者 Tab 页

https://www.selenium.dev/documentation/webdriver/browser/windows/

driver.switchTo().newWindow()

创建多个Window

// 打开并切换到新的窗口
const windowHandle = await driver.switchTo().newWindow('window');
await driver.navigate().to('http://0.0.0.0:80') 
// 打开并切换到新的窗口
const otherWindowHandle = await driver.switchTo().newWindow('window');
await driver.navigate().to('http://0.0.0.0:8080')
... ...

// 切换到 windowHandle 窗口
driver.switchTo().window(windowHandle);
// 切换到 otherWindowHandle 窗口
driver.switchTo().window(otherWindowHandle);

多个Tab页操作

创建新的Tab页,打开指定链接,并返回该Tab页的操作 句柄 (Tab标识符)

https://www.selenium.dev/documentation/webdriver/browser/windows/#switching-windows-or-tabs

async function getTap (url) {
  await driver.switchTo().newWindow()
  await driver.navigate().to(url)
  const qqlWindowHandle = await driver.getWindowHandle();
  return qqlWindowHandle
}

完整示例

// index.js 

const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');

/**
 * 获取驱动服务
 * 浏览器驱动启动后,会挂载到一个端口上我们可以通过HTTP服务访问、操作浏览器
 */
const service = new chrome.ServiceBuilder('/Users/shang/Code/github/webdriver/chromedriver');
// 获取Chrome浏览器配置
const options = new chrome.Options();

options.setChromeLogFile('/Users/shang/Downloads/chrome.log');
// 
const arguments = [
  '--disable-web-security', // 关闭浏览器安全设置,如:浏览器跨域
  // '--incognito', // 使用隐身模式
  // '--user-data-dir=/Users/shang/Downloads/chromeincognito' // 设置当前用户的工作目录
]
options.addArguments.apply(options, arguments);

(async () => {

// 创建一个浏览器驱动
const driver = await new Builder()
  .setChromeOptions(options)
  .forBrowser('chrome')
  .setChromeService(service)
  .build()

async function getTap (url) {
  await driver.switchTo().newWindow()
  await driver.navigate().to(url)
  const qqlWindowHandle = await driver.getWindowHandle();
  return qqlWindowHandle
}

const qqWindowHandle = await getTap('https://www.qq.com')
const baiduWindowHandle = await getTap('https://www.baidu.com')

// 等待2秒
await new Promise((resolve) => { setTimeout(resolve, 2000) })
// 切换到 QQ 所在窗口
await driver.switchTo().window(qqWindowHandle);
// 执行JavaScript方法 所在窗口
await driver.executeScript(function (handle) {
  console.log('output handle qq', handle, window.document.title)
}, qqWindowHandle)

// 等待2秒
await new Promise((resolve) => { setTimeout(resolve, 2000) })
// 切换到 百度 所在窗口
await driver.switchTo().window(baiduWindowHandle);
// 执行JavaScript方法 所在窗口
await driver.executeScript(function (handle) {
  console.log('output handle baidu', handle, window.document.title)
}, qqWindowHandle)

await new Promise((resolve) => { setTimeout(resolve, 2000) })

// 退出浏览器
driver.quit()

})();

执行测试任务

node index.js

示例日志结果

[12369:259:0822/115042.778808:INFO:CONSOLE(306)] "每一个星球都有一个驱动核心,
每一种思想都有影响力的种子。
感受世界的温度,
年轻的你也能成为改变世界的动力,
百度珍惜你所有的潜力。
你的潜力,是改变世界的动力!

", source: https://pss.bdstatic.com/r/www/cache/static/protocol/https/global/js/all_async_search_098edf7.js (306)
[12369:259:0822/115042.778926:INFO:CONSOLE(306)] "%c百度2022校园招聘简历投递:https://talent.baidu.com/external/baidu/campus.html color:red", source: https://pss.bdstatic.com/r/www/cache/static/protocol/https/global/js/all_async_search_098edf7.js (306)
[12369:259:0822/115046.448069:INFO:CONSOLE(4)] "output handle qq CDwindow-2F3C312D42DF8A638BA8C5322A85B541 腾讯首页", source:  (4)
[12369:259:0822/115049.493448:INFO:CONSOLE(4)] "output handle baidu CDwindow-2F3C312D42DF8A638BA8C5322A85B541 百度一下,你就知道", source:  (4)

抛砖引玉

实现自动化测试

  1. 把要使用的方法通过 Demo 挂载到全局。

  2. 实现多用户多场景登录。

    1. 多tab页,
    2. 多window窗口,
    3. 多浏览器,
    4. 多设备,[ WebDriver Remote Server ]
  3. 通过调用 Demo 上挂载的 全局变量 实现具体的功能操作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

从未、淡定

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

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

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

打赏作者

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

抵扣说明:

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

余额充值