Skip to main content

Web UI 自动化技术

·1400 字·3 分钟
开发 开源
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…