三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

WebDriver API核心原理与实战:构建稳定高效的UI自动化测试

WebDriver API核心原理与实战:构建稳定高效的UI自动化测试

1. 项目概述:为什么WebDriver API是自动化测试的基石

如果你刚开始接触UI自动化测试,或者已经用Selenium写过一些脚本,但总觉得代码写得不够“优雅”、不够健壮,那多半是因为你还没有系统地掌握WebDriver API。很多人把Selenium等同于“定位元素”和“click()”,这其实只看到了冰山一角。WebDriver API是Selenium的核心,它定义了一套与浏览器进行通信的标准化协议(W3C WebDriver标准),让你能像真人用户一样,通过代码精确地控制浏览器的每一个行为。

我见过不少测试脚本,充斥着大量的Thread.sleep(),或者因为一个弹窗、一个异步加载就导致整个测试用例失败。这些问题,本质上都是对WebDriver API提供的丰富能力了解不足。WebDriver API不仅仅能帮你打开网页、点击按钮,它还能处理复杂的用户交互、等待条件、执行JavaScript、管理Cookie、窗口、弹窗,甚至模拟键盘和鼠标的高级操作。掌握它,意味着你能写出更稳定、更高效、更易于维护的自动化测试脚本。这篇文章,我会带你从零开始,深入WebDriver API的每一个关键角落,不只是教你“怎么用”,更会告诉你“为什么这么用”,以及在实际项目中如何避开那些常见的“坑”。

2. WebDriver API核心架构与工作原理拆解

在开始写代码之前,我们必须先理解WebDriver是怎么工作的。这能帮你从根本上理解后续所有API调用的行为,并在出现问题时快速定位。

2.1 核心组件:客户端、服务端与浏览器驱动

WebDriver的工作模式是经典的客户端-服务器架构。

  1. 客户端 (Client Library): 这就是你写的测试代码,比如用Python的selenium包,Java的selenium-java,或者Node.js的selenium-webdriver。它提供了一套友好的API给你调用。
  2. WebDriver服务端 (WebDriver Server): 通常指的是selenium-server-standalone.jar或浏览器特定的驱动(如chromedriver,geckodriver)。它扮演了一个HTTP服务器的角色。
  3. 浏览器驱动 (Browser Driver): 严格来说,chromedriver这类既是驱动也是服务端。它负责接收来自客户端的HTTP请求(遵循W3C WebDriver协议),并将其翻译成浏览器能理解的内部命令(如Chrome DevTools Protocol)来操控真实的浏览器。

工作流程:你的代码(客户端)发送一个HTTP请求(例如“打开某个URL”)到chromedriver(服务端)。chromedriver解析这个请求,通过CDP等协议让Chrome浏览器执行对应操作。浏览器执行完毕后,将结果(如页面标题、元素状态)返回给chromedriverchromedriver再封装成HTTP响应返回给你的代码。

注意:这就是为什么你必须下载并正确配置浏览器驱动,且驱动版本要与浏览器版本匹配。版本不匹配是新手最常见的“浏览器打不开”或“莫名报错”的原因之一。

2.2 会话(Session)管理:一切交互的起点

当你执行driver = webdriver.Chrome()时,底层发生了一件关键事情:客户端向服务端发送了一个POST /session请求。服务端会启动一个新的浏览器实例,并创建一个唯一的sessionId返回给客户端。后续所有针对这个浏览器的操作(如driver.get(),driver.find_element()),都会在HTTP请求中携带这个sessionId,以指明操作对象。

# Python示例:创建会话的本质 from selenium import webdriver # 这行代码背后,是向`http://localhost:9515/session`发送了一个POST请求 # 请求体包含了如`{"capabilities": {...}}`的配置信息 driver = webdriver.Chrome() # 返回的driver对象内部就保存了这个会话的ID

为什么重要?理解会话概念,你就能明白:

  • 并行测试:你可以创建多个driver对象,即多个独立会话,同时运行多个浏览器实例。
  • 远程测试:你可以将客户端指向一个远程的selenium-server(如Selenium Grid或云测平台),只需在创建会话时指定远程服务器的地址,会话将在远程机器上创建。
  • 清理资源:测试结束后必须调用driver.quit()。这个API会向服务端发送DELETE /session/{sessionId}请求,优雅地关闭浏览器并释放资源。直接关闭Python进程或使用driver.close()(仅关闭当前标签页)可能导致远程的浏览器进程成为“僵尸进程”。

3. 元素定位与交互:超越find_element和click

定位元素是自动化测试最基础也最频繁的操作。WebDriver提供了8种内置定位器(By策略)。

3.1 八大定位策略详解与选用原则

定位器示例 (Python)适用场景与注意事项
IDfind_element(By.ID, “kw”)最高优先级。ID通常唯一且稳定。但需注意前端框架(如Vue, React)可能生成动态ID。
Namefind_element(By.NAME, “wd”)常用于表单元素。需确保name属性在当前页面唯一。
Class Namefind_element(By.CLASS_NAME, “s_ipt”)注意一个元素可能有多个class(如class=”btn btn-primary”),传入时需用完整的一个,不能包含空格。
Tag Namefind_element(By.TAG_NAME, “input”)通常用于获取某一类元素的集合,如find_elements(By.TAG_NAME, “tr”)获取表格所有行。
Link Textfind_element(By.LINK_TEXT, “登录”)精确匹配超链接的完整可见文本。
Partial Link Textfind_element(By.PARTIAL_LINK_TEXT, “录”)模糊匹配超链接的部分可见文本。当链接文本较长或部分动态时有用。
CSS Selectorfind_element(By.CSS_SELECTOR, “#form .btn-submit”)功能最强大、最常用。语法丰富,可通过id、class、属性、层级关系等组合定位。性能通常优于XPath。
XPathfind_element(By.XPATH, “//input[@id=‘kw’]”)功能强大但复杂。可以遍历整个DOM树,支持轴(axis)定位。绝对路径(以/开头)脆弱,务必使用相对路径

实操心得:定位策略选型

  1. 首选ID:如果元素有稳定ID,毫不犹豫用它。
  2. 次选CSS Selector:对于没有ID的元素,CSS Selector是首选。它更简洁,浏览器的原生支持使其速度很快。例如,定位一个具有>from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By driver.get(“https://example.com”) menu = driver.find_element(By.CSS_SELECTOR, “.dropdown-menu”) submenu = driver.find_element(By.CSS_SELECTOR, “.dropdown-item-special”) # 创建一个动作链:移动到菜单 -> 暂停 -> 移动到子菜单 -> 点击 actions = ActionChains(driver) actions.move_to_element(menu).pause(1).move_to_element(submenu).click().perform() # 注意:所有动作存储在链中,调用`.perform()`时才真正执行。

    为什么用ActionChains而不是连续click对于级联菜单,直接click(menu)可能只是展开菜单,而move_to_element能更精确地模拟用户的鼠标悬停行为。

    键盘操作除了send_keys(“text”),还可以发送组合键。

    from selenium.webdriver.common.keys import Keys search_box = driver.find_element(By.NAME, “q”) search_box.send_keys(“selenium”) # 输入文本 search_box.send_keys(Keys.CONTROL, “a”) # 全选 (Ctrl+A) search_box.send_keys(Keys.BACKSPACE) # 删除 search_box.send_keys(Keys.ENTER) # 回车搜索

    处理文件上传文件上传输入框(<input type=”file”>)不能使用send_keys(“文件路径”)吗?可以,但前提是这个input元素是可见且可交互的。对于通过JavaScript隐藏或美化的上传组件,可能需要先通过JavaScript让原生input元素可见,或者使用driver.execute_script()直接设置其value(注意,由于安全限制,并非所有浏览器都支持后者)。更通用的做法是,利用AutoITpywin32等工具模拟操作系统级的文件选择对话框,但这超出了WebDriver范围,且跨平台性差。

    实操避坑:send_keys的字符集问题在非英文系统或输入特殊字符时,send_keys可能出错。一个可靠的技巧是,将要输入的文本拆分成单个字符发送,或使用ActionsChainssend_keys_to_element

    # 可能更稳定的方式 text = “你好,世界!” for char in text: element.send_keys(char) time.sleep(0.05) # 微小延迟,模拟真人输入

    4. 等待机制:让自动化脚本稳定运行的关键

    动态加载是现代Web应用的常态。元素还没加载出来你就去点击,脚本当然会报NoSuchElementException。等待是自动化脚本稳定的灵魂。

    4.1 三种等待方式深度解析

    1. 强制等待 (Hard-coded Sleep):time.sleep(5)

      • 是什么:让线程暂停指定时间。
      • 为什么(几乎)永远不要用:无论页面是否加载完成,它都会死等。时间设短了元素没出来,设长了浪费执行时间。它让测试变得缓慢且不可靠。
    2. 隐式等待 (Implicit Wait):driver.implicitly_wait(10)

      • 是什么:为driver对象设置一个全局的等待时间。在尝试查找任何一个元素时,如果元素没有立即出现,WebDriver会轮询DOM(默认每0.5秒)直到元素被找到或超时。
      • 怎么用:通常在创建driver后立即设置一次,对整个会话生效。
      driver = webdriver.Chrome() driver.implicitly_wait(10) # 单位:秒
      • 注意事项
        • 它只对find_elementfind_elements方法生效。
        • 它不关心元素是否可交互(如可点击、可见)。元素在DOM中存在但被遮挡或禁用,隐式等待不会继续等待。
        • 混合使用隐式等待和显式等待可能导致不可预料的超时行为,最佳实践是只用一种,推荐显式等待。
    3. 显式等待 (Explicit Wait):WebDriverWait(driver, 10).until(...)

      • 是什么:针对某个特定条件进行等待,条件满足则立即继续,否则在超时后抛出TimeoutException。这是最推荐、最强大的等待方式。
      • 核心组件
        • WebDriverWait(driver, timeout): 等待器。
        • expected_conditions(EC): 预定义的一系列等待条件。
        • until(method): 等待条件满足。

    4.2 Expected Conditions 实战详解

    expected_conditions模块提供了丰富的条件判断。以下是一些最常用的:

    元素存在与可见

    • presence_of_element_located(locator):元素出现在DOM中。不一定可见(可能隐藏)。这是find_element的“等待版”。
    • visibility_of_element_located(locator):元素出现在DOM中且可见(宽高大于0)。这是与元素交互(如点击)前的首选检查条件

    元素可交互状态

    • element_to_be_clickable(locator):元素可见且启用(enabled)。这是执行click()操作前的黄金标准。
    • element_to_be_selected(element): 用于复选框(checkbox)或单选框(radio)是否被选中。

    页面与文本状态

    • title_is(title): 页面标题完全等于预期字符串。
    • title_contains(partial_title): 页面标题包含某字符串。
    • text_to_be_present_in_element(locator, text_): 指定元素内部包含预期文本。
    • url_to_be(url): 当前URL完全等于预期。
    • url_contains(partial_url): 当前URL包含某字符串。

    等待多个元素

    • presence_of_all_elements_located(locator): 等待至少一个元素出现。
    • visibility_of_any_elements_located(locator): 等待至少一个元素可见。

    综合示例:一个健壮的登录操作

    from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException def login(driver, username, password): try: # 1. 等待登录按钮出现并可点击 login_button = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.CSS_SELECTOR, “.btn-login”)) ) login_button.click() # 2. 等待用户名输入框可见 username_input = WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.ID, “username”)) ) username_input.clear() username_input.send_keys(username) # 3. 输入密码 password_input = driver.find_element(By.ID, “password”) # 因为上一步已等待页面稳定,这里可以直接定位 password_input.send_keys(password) # 4. 等待提交按钮可点击后点击 submit_btn = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.NAME, “submit”)) ) submit_btn.click() # 5. 等待登录成功后的页面元素(如用户头像)出现,作为断言 WebDriverWait(driver, 15).until( EC.presence_of_element_located((By.CLASS_NAME, “user-avatar”)) ) print(“登录成功!”) return True except TimeoutException as e: print(f”登录超时或失败: {e}”) # 这里可以截图,方便排查 driver.save_screenshot(“login_failure.png”) return False

    自定义等待条件当内置条件不满足时,你可以用lambda函数或自定义函数创建任何等待条件。

    # 等待某个元素的特定属性值出现 wait = WebDriverWait(driver, 10) element = wait.until(lambda d: d.find_element(By.ID, “progress”).get_attribute(“value”) == “100”) # 等待页面某个JavaScript变量被设置 is_loaded = wait.until(lambda d: d.execute_script(“return window.pageLoaded === true;”))

    核心技巧:将显式等待封装成你自己的工具函数。例如,一个安全的点击函数:

    def safe_click(driver, locator, timeout=10): element = WebDriverWait(driver, timeout).until( EC.element_to_be_clickable(locator) ) element.click()

    这样,你的业务代码里就几乎看不到WebDriverWait,变得非常清晰。

    5. 浏览器导航、窗口与弹窗处理

    5.1 页面导航与历史记录

    • driver.get(url): 导航到新页面。它会等待页面完全加载(即document.readyStatecomplete。但对于大量AJAX的应用,这还不够,仍需配合显式等待。
    • driver.back()/driver.forward(): 模拟浏览器后退/前进按钮。
    • driver.refresh(): 刷新当前页面。

    注意get()的陷阱:对于单页应用(SPA),get()可能很快返回,因为初始HTML加载完了,但应用本身还在异步加载数据渲染视图。此时必须使用显式等待来等待具体业务元素,而不是依赖get()的自动等待。

    5.2 多窗口与多标签页处理

    当点击一个链接(target=”_blank”)或脚本打开新窗口时,需要切换上下文。

    # 获取当前窗口句柄 main_window = driver.current_window_handle # 点击打开新窗口的链接 driver.find_element(By.LINK_TEXT, “在新窗口打开”).click() # 获取所有窗口句柄 all_handles = driver.window_handles # 返回一个列表 new_window = [handle for handle in all_handles if handle != main_window][0] # 切换到新窗口 driver.switch_to.window(new_window) # 在新窗口操作 print(driver.title) # 操作完毕后,可以关闭新窗口并切回主窗口 driver.close() # 关闭当前(新)窗口 driver.switch_to.window(main_window) # 切回原窗口

    5.3 处理Alert、Confirm、Prompt弹窗

    WebDriver提供了Alert接口来处理JavaScript原生弹窗。

    from selenium.webdriver.common.alert import Alert # 触发一个alert driver.find_element(By.ID, “trigger-alert”).click() # 等待alert出现并切换到它 WebDriverWait(driver, 5).until(EC.alert_is_present()) alert = Alert(driver) # 获取弹窗文本 print(alert.text) # 接受(点击“确定”) alert.accept() # 对于confirm弹窗,还可以取消(点击“取消”) # alert.dismiss() # 对于prompt弹窗,可以输入文本 # alert.send_keys(“Your input”) # alert.accept()

    重要:必须在操作弹窗前switch_to.alert,操作完成后,WebDriver会自动将上下文切换回原来的页面。

    5.4 处理iframe/框架

    要操作iframe内部的元素,必须先切换到对应的iframe。

    # 通过ID或Name切换 driver.switch_to.frame(“iframe-id”) # 或通过索引(从0开始) driver.switch_to.frame(0) # 或通过定位到的WebElement iframe_element = driver.find_element(By.TAG_NAME, “iframe”) driver.switch_to.frame(iframe_element) # 在iframe内操作元素 driver.find_element(By.ID, “inside-iframe”).click() # 操作完成后,切回主文档 driver.switch_to.default_content() # 或者切回上一级父框架 # driver.switch_to.parent_frame()

    常见坑:在iframe里操作完后忘记切回来,导致后续定位一直在错误的上下文中进行,报NoSuchElementException

    6. 执行JavaScript与高级浏览器操作

    WebDriver的强大之处在于,当标准API无法满足时,你可以直接“操纵”浏览器。

    6.1execute_script:无所不能的利器

    driver.execute_script(script, *args)允许你在当前页面上下文中执行任意JavaScript。

    # 示例1:滚动页面 # 滚动到页面底部 driver.execute_script(“window.scrollTo(0, document.body.scrollHeight);”) # 滚动到指定元素 element = driver.find_element(By.ID, “my-element”) driver.execute_script(“arguments[0].scrollIntoView(true);”, element) # true表示与顶部对齐 # 示例2:修改元素属性或样式(用于调试或处理特殊场景) driver.execute_script(“document.getElementById(‘hidden-input’).type = ‘text’;”) driver.execute_script(“arguments[0].style.border = ‘3px solid red'”, element) # 高亮元素 # 示例3:获取页面详细信息(比WebDriver API更快) title = driver.execute_script(“return document.title;”) window_size = driver.execute_script(“return {width: window.innerWidth, height: window.innerHeight};”) # 示例4:处理原生点击失效的场景 # 有些元素(如某些基于SVG或Canvas的组件)可能对WebDriver的click()不响应,可以用JS点击 driver.execute_script(“arguments[0].click();”, element)

    返回值execute_script可以返回JavaScript执行的结果,支持基本类型、数组、对象等,非常方便。

    6.2 浏览器信息与Cookie管理

    • 浏览器信息:
      driver.current_url # 当前URL driver.title # 页面标题 driver.page_source # 页面完整HTML源码(慎用,可能很大) driver.get_window_size() # 获取窗口大小 driver.set_window_size(1024, 768) # 设置窗口大小 driver.maximize_window() # 最大化窗口 driver.get_screenshot_as_file(“./screenshot.png”) # 截图,用于失败分析或报告
    • Cookie管理:
      # 获取所有cookie all_cookies = driver.get_cookies() # 按名称获取特定cookie session_cookie = driver.get_cookie(“sessionid”) # 添加cookie (常用于绕过登录或保持会话) driver.add_cookie({‘name’: ‘token’, ‘value’: ‘abc123’, ‘domain’: ‘.example.com’}) # 注意:添加cookie必须在当前域下,通常先get(domain)再add_cookie # 删除所有cookie driver.delete_all_cookies()

    7. 实战:构建一个健壮的页面操作模型(Page Object Model, POM)

    掌握了所有API后,如何组织代码?直接在所有测试用例里写定位和操作,会导致代码极度冗余、难以维护。这时需要引入页面对象模型(POM)

    POM的核心思想是将一个页面的元素定位和操作封装成一个类。测试用例只与页面对象的方法交互,不关心具体定位细节。

    基础POM示例:登录页面

    # pages/login_page.py from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class LoginPage: def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10) # 定位器 (Locators) USERNAME_INPUT = (By.ID, “username”) PASSWORD_INPUT = (By.ID, “password”) LOGIN_BUTTON = (By.CSS_SELECTOR, “button[type=’submit’]”) ERROR_MESSAGE = (By.CLASS_NAME, “alert-error”) # 页面操作方法 def enter_username(self, username): element = self.wait.until(EC.visibility_of_element_located(self.USERNAME_INPUT)) element.clear() element.send_keys(username) return self # 支持链式调用 def enter_password(self, password): self.driver.find_element(*self.PASSWORD_INPUT).send_keys(password) return self def click_login(self): self.wait.until(EC.element_to_be_clickable(self.LOGIN_BUTTON)).click() def get_error_message(self): try: return self.driver.find_element(*self.ERROR_MESSAGE).text except: return None # 一个完整的业务流方法 def login(self, username, password): self.enter_username(username) self.enter_password(password) self.click_login() # 可以返回下一个页面的对象,例如HomePage # return HomePage(self.driver)

    在测试用例中使用

    # tests/test_login.py import pytest from pages.login_page import LoginPage def test_successful_login(driver): # 假设driver通过fixture提供 login_page = LoginPage(driver) driver.get(“https://example.com/login”) # 清晰、可读的业务流 login_page.login(“valid_user”, “valid_pass”) # 断言:验证登录后跳转或出现成功元素 assert “Dashboard” in driver.title def test_failed_login(driver): login_page = LoginPage(driver) driver.get(“https://example.com/login”) login_page.login(“invalid”, “invalid”) error_msg = login_page.get_error_message() assert error_msg is not None assert “Invalid credentials” in error_msg

    POM的优势

    1. 代码复用:定位器集中管理,修改页面元素时只需改一个地方。
    2. 可读性高:测试用例读起来像自然语言。
    3. 可维护性强:页面逻辑与测试逻辑分离。
    4. 减少重复:常见的页面操作(如等待、点击)可以封装在基类中。

    8. 常见问题排查与调试技巧实录

    即使掌握了API,在实际运行中还是会遇到各种问题。这里记录了我踩过的一些坑和解决方法。

    8.1 元素定位失败(NoSuchElementException)

    这是最常见的问题。

    1. 检查定位器:首先在浏览器的开发者工具(F12)的Console里用JavaScript验证你的定位器是否正确。例如:$$(“#kw”)(Chrome) 或$x(“//input[@id=’kw’]”)
    2. 检查iframe:目标元素是否在iframe里?如果是,需要先switch_to.frame
    3. 检查时机(等待):元素是否已经加载/可见?99%的定位失败都是因为没加合适的等待。使用visibility_of_element_locatedelement_to_be_clickable
    4. 检查元素是否在Shadow DOM中:现代Web组件可能使用Shadow DOM。WebDriver标准支持Shadow Root访问,但需要特殊处理:
      # 假设有一个自定义组件 <my-component> host = driver.find_element(By.TAG_NAME, “my-component”) shadow_root = driver.execute_script(“return arguments[0].shadowRoot”, host) # 然后通过shadow_root来查找内部元素 inner_element = shadow_root.find_element(By.CSS_SELECTOR, “.inner-class”)
    5. 检查页面是否发生了跳转或刷新:定位前页面状态是否稳定?有时点击一个按钮后,页面会刷新或跳转,之前的元素引用就失效了。需要在操作后重新定位。

    8.2 元素不可交互(ElementNotInteractableException)

    元素找到了,但点击或输入时报错。

    1. 元素被遮挡:可能有另一个元素(如弹窗、遮罩层)盖在了上面。使用driver.execute_script(“arguments[0].click();”, element)进行JS点击有时能绕过。
    2. 元素不可见:检查CSS的display: nonevisibility: hidden属性。确保使用visibility_of_element_located等待。
    3. 元素被禁用:检查disabled属性。需要等待其变为启用状态,或检查业务逻辑是否正确。
    4. 需要滚动到视图:元素不在当前可视区域内。使用scrollIntoView
      driver.execute_script(“arguments[0].scrollIntoView({block: ‘center’});”, element) WebDriverWait(driver, 5).until(EC.element_to_be_clickable(locator)).click()

    8.3 超时问题(TimeoutException)

    显式等待超时。

    1. 增加超时时间:对于慢网络或复杂操作,适当增加WebDriverWait的第二个参数。
    2. 检查条件是否正确:确认你等待的条件确实会在页面上发生。有时业务逻辑变了,等待的元素永远不会出现。
    3. 使用更宽松的条件:比如用presence_of_element_located代替visibility_of_element_located,如果只关心元素是否存在。
    4. 结合自定义等待:在等待中加入更复杂的逻辑。

    8.4 浏览器驱动版本不匹配

    症状:浏览器无法启动,或启动后立刻崩溃。

    • 解决方案:始终使用与浏览器版本匹配的驱动。ChromeDriver版本支持页面会明确说明支持的Chrome版本范围。一个实用的技巧是使用webdriver-manager(Python)或selenium-webdriverService类自动管理驱动,但生产环境建议固定版本以保证稳定性。

    8.5 处理不稳定的异步操作

    对于极度动态、难以用常规条件等待的场景(如一个复杂的图表渲染完成),可以尝试轮询检查某个特定状态。

    def wait_for_complex_condition(driver, timeout=30): start_time = time.time() while time.time() - start_time < timeout: # 通过执行JS检查页面上的某个标志 is_done = driver.execute_script(“return window.myApp && window.myApp.isDataLoaded;”) if is_done: return True time.sleep(0.5) # 轮询间隔 raise TimeoutException(“复杂条件未在指定时间内满足”)

    8.6 启用浏览器日志和性能日志

    在创建驱动时添加选项,可以捕获浏览器控制台日志和性能日志,对于调试JavaScript错误或网络问题非常有帮助。

    from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.desired_capabilities import DesiredCapabilities caps = DesiredCapabilities.CHROME caps[‘goog:loggingPrefs’] = { ‘browser’: ‘ALL’, ‘performance’: ‘ALL’ } chrome_options = Options() # … 其他选项 driver = webdriver.Chrome(desired_capabilities=caps, options=chrome_options) # 之后可以获取日志 for entry in driver.get_log(‘browser’): print(entry) for entry in driver.get_log(‘performance’): print(entry)

    WebDriver API是一座宝库,远不止本文所涵盖的内容。但只要你掌握了上述核心概念——会话管理、稳健的定位与等待、复杂的交互、以及POM设计模式,你就已经具备了解决绝大多数Web自动化测试需求的能力。剩下的就是结合具体项目,不断实践和积累。记住,好的自动化测试代码应该是健壮、清晰且易于维护的,而这很大程度上取决于你对WebDriver API的理解和运用是否到位。

← 返回列表