Web UI 自动化技术
Table of Contents
Web 自动化技术可以应用最常见的领域是 e2e 系统集成测试,爬虫,抢票等。
WebDriver & Selenium #
WebDriver 是 W3C 制定一个浏览器自动化协议 Automation Protocols | WebdriverIO,它定义了一套标准 REST JSON API,允许自动化测试工具与不同的浏览器进行交互。Selenium 是建立在 WebDriver 之上的一个自动化测试框架,它提供了一套完整的 WebDriver API 用于控制浏览器,包括输入、点击、下拉等。实际的自动化幕后由 Chrome Driver 完成(针对不同的浏览器有不同的 Driver)。Chrome Driver 就是个 HTTP 服务器,启动时会通过 Chrome debugger 连接 Chrome。
由于使用时间非常长久,所以非常稳定,而且支持全部常见的开发语言和主流浏览器,是目前 Web 自动化和测试最常用的选择。Selenium 支持浏览器可以在两种方式下运行 - headless
或者 headed
headless 方式下是没有 UI 界面的,没有用户互动,输入输出都在后台完成。同时可以和很多测试工具结合,并且也支持大规模的开发测试,如 Selenuim Grid,支持移动端测试,如 Appium。
由于 WebDriver 只是个单向的 REST JSON API,有些工作如收集 network events 或者 console logs 比较困难。
一个 Selenium + Python 的例子:
# -*- coding: utf8 -*-
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver import ActionChains
DRIVER_PATH = r"/Users/fastzhong/chromedriver_mac64/chromedriver"
CHROME_OPTS = Options()
URL = "https://google.com"
def search(txt):
# Chrome will be used
driver = webdriver.Chrome(service=Service(DRIVER_PATH), options=CHROME_OPTS)
# opening the website
driver.get(URL)
# set timeout
wait = WebDriverWait(driver, 10)
# locate search box using its id
search_box = wait.until(EC.presence_of_element_located((By.ID, "APjFqb")))
# search txt
action = ActionChains(driver)
action.move_to_element(search_box).click().send_keys(txt).send_keys("\n").perform()
# sleep 300 seconds
time.sleep(300)
# close the session
driver.close()
if __name__ == "__main__":
search("selenium")
Puppeteer & Playwright #
随着 Chrome 一统浏览器江湖,Chrome DevTools 也跟着兴起,除了 WebDriver 之外,Chrome 还提供了 Chrome DevTools Protocol,它也定义了一套标准 API,与 Chrome 进行交互(Web Socket)。基于 Chrome DevTools Protocol, Google 自家搞出的工具 Puppeteer,官方只支持 Chrome 和 Javascript(Puppeteer 依赖 Node.js)。然后这帮人跑出来加入了微软,搞出个类似的 Playwright,支持其它浏览器以及其它编程语言,Javascirpt API 也有所改进(不再需要 wait,参考 Migrating from Puppeteer | Playwright)。Puppeteer 和 Playwright 比 Selenium 更吸引 Web/Javascript 开发者,运行速度快,但是从功能、稳定性到社区规模,还是远远不能比的。
一个 Puppeteer 的例子:
const puppeteer = require('puppeteer');
(async () => {
const url = 'https://google.com';
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.setViewport({ width: 0, height: 0 });
try {
// open the website
await page.goto(url);
// locate search box using its id
const searchBox = await page.$('#APjFqb');
// entery search text
searchBox.type('puppeteer\n');
// pause 300 secs
await new Promise((r) => setTimeout(r, 300000));
} catch (err) {
console.log(err);
} finally {
await browser.close();
}
})();
我不喜欢 Javascript 的语法,之前编程要用 call back,把逻辑搞得支离破碎,现在改进,但到处是 await。 |
其它 #
编程语言通常都有通用,底层,支持 URL/HTTP 的库,如 Javascript 的 Axios、 got,Python 的 requests,Java 的 HttpClient,通过这些库可以完成简单的 Web 请求和响应,也可以扩展完成各式各样的复杂任务,他们也是很多大型爬虫框架的底层库,最常使用的地方就是 API 测试,性能测试,和定制爬虫, 优点是能通过代码能够做到大量底层定制,大规模并发, 缺点是不适合浏览器环境下 UI 的输入、输出及控制,以及需要运行复杂的前端逻辑(例如需要 Javascript 引擎及 DOM 操作),由于是底层 HTTP,代码量大,开发慢。
此外还有一些专门的 Javascript 测试库/框架,如: Jest、 Mocha、 Vitest、 Cypress 等,这些虽然可以直接操作 DOM 用于测试但也不适用控制浏览器/UI。
我写过多个商业级爬虫,除了 UI 自动化,还有其它技术细节。关于 UI 自动化测试,参考老专家 Zhimin Zhan – Medium 的文章,里面有很多技术讨论和细节: AgileWay Test Automation Formula. A proven combination of frameworks and… |