Python UI自动化实战:从Selenium到Playwright,工具选型与框架搭建全解析

1. 项目概述:为什么我们需要Python UI自动化?

如果你是一名测试工程师、开发人员,或者任何需要与软件界面反复打交道的人,那么“UI自动化”这个词对你来说一定不陌生。想象一下,每天上班第一件事,就是打开某个软件,点击同样的菜单,输入同样的数据,然后等待结果,日复一日。这种重复、机械的操作,不仅枯燥乏味,还容易因为人的疲劳而出错。而Python UI自动化,就是解放你双手、提升效率和准确性的那把“瑞士军刀”。

简单来说,Python UI自动化就是用Python脚本,模拟人的操作,去控制电脑上的软件界面。无论是点击按钮、输入文字、下拉选择,还是验证页面上的某个元素是否存在,这些都可以交给脚本来完成。它的核心价值在于将重复性劳动自动化,把宝贵的人力资源投入到更有创造性的工作中去。比如,在软件开发中,每次发布新版本前,都需要对核心功能进行回归测试,手动执行一遍可能需要几个小时,而自动化脚本可能只需要几分钟。再比如,你需要每天从某个没有开放API的网站上抓取数据,手动复制粘贴不仅慢,格式还容易乱,写一个自动化脚本就能定时、精准地完成。

Python之所以成为UI自动化的首选语言,原因有几个:首先,它的语法简洁易懂,学习曲线平缓,即便是编程新手也能快速上手写出可用的脚本。其次,Python拥有一个极其庞大和活跃的生态系统,针对各种UI自动化场景都有成熟、强大的库支持,比如用于Web自动化的Selenium和Playwright,用于桌面应用自动化的PyAutoGUI和pywinauto,以及用于移动端自动化的Appium。最后,Python的跨平台特性很好,同一套脚本经过少量调整,往往可以在Windows、macOS和Linux上运行。结合最新的网络热词来看,无论是“playwright自动化框架”的高性能与现代化,还是“n8n工作流自动化”所代表的流程编排思想,都说明了自动化正朝着更智能、更集成的方向发展。而“ai自动化测试”更是预示了未来结合AI进行智能元素定位、自愈脚本等前沿趋势。

所以,无论你是想告别枯燥的重复点击,还是想构建一套稳定的自动化测试体系,亦或是实现一些个性化的办公自动化,掌握Python UI自动化都是一项极具性价比的技能。接下来,我将以一个从业者的视角,为你拆解从环境搭建到脚本编写,再到框架设计的完整路径,并分享那些只有踩过坑才知道的实战经验。

2. 核心工具选型:Selenium, Playwright 还是 PyAutoGUI?

工欲善其事,必先利其器。开始编写UI自动化脚本前,第一个关键决策就是选择工具库。市面上主流的Python UI自动化库各有侧重,选对了工具,项目就成功了一半。这里我们重点对比三个最常用、也最具代表性的工具:Selenium、Playwright和PyAutoGUI。

2.1 Web自动化双雄:Selenium vs. Playwright

如果你的自动化对象是浏览器中的网页,那么Selenium和Playwright是你的主要选择。

Selenium:经典且稳健的行业标准Selenium WebDriver是UI自动化领域当之无愧的“老大哥”,拥有超过十年的历史和最广泛的社区支持。它的核心原理是通过浏览器厂商提供的驱动(如ChromeDriver、geckodriver),向浏览器发送标准化的WebDriver协议命令,从而控制浏览器。

  • 优势
    1. 生态成熟:几乎所有你能想到的浏览器都支持,社区资源(教程、问答、第三方工具)极其丰富。遇到问题,几乎都能在网上找到解决方案。
    2. 语言无关:虽然我们用Python,但Selenium支持Java、C#、JavaScript等多种语言,团队技术栈兼容性好。
    3. 行业认可度高:是绝大多数企业自动化测试框架的基石,相关面试题(如“自动化测试面试题”)也常围绕它展开。
  • 劣势
    1. 速度相对较慢:由于通信协议和架构原因,执行速度不如一些新兴框架。
    2. 等待机制需要手动处理:需要显式地编写等待代码(WebDriverWait)来处理页面加载或元素出现的异步问题,对新手不够友好。
    3. 对现代Web技术的原生支持稍弱:例如,处理Shadow DOM、网络拦截等高级特性需要额外配置或依赖第三方库。

Playwright:微软出品的现代新贵Playwright是近几年由微软开源的新一代浏览器自动化库,它生来就是为了解决Selenium的一些痛点。

  • 优势
    1. 执行速度快:采用无头浏览器(Headless)优先的设计,并且与浏览器内核通信更高效。
    2. 自动等待:Playwright的大多数操作(如click,fill)内置了智能等待,它会自动等待元素可操作(可见、可点击、稳定等),大大简化了脚本编写。
    3. 强大的网络与上下文控制:可以轻松模拟移动设备、地理位置、权限(如摄像头),拦截和修改网络请求,录制视频等,功能非常强大。
    4. 多浏览器支持:一套API同时支持Chromium、Firefox和WebKit(Safari引擎)。
  • 劣势
    1. 相对较新:社区生态和第三方集成工具不如Selenium丰富,一些非常边缘的问题可能资料较少。
    2. 学习资源:虽然文档优秀,但中文社区和传统教程数量目前还不及Selenium。

选择建议:对于全新的项目,尤其是需要处理复杂SPA(单页应用)或对执行速度、稳定性要求高的场景,我强烈推荐从Playwright开始。它的“自动等待”特性能帮你避开UI自动化中最常见的“元素未找到”错误,显著提升开发效率和脚本健壮性。如果是维护遗留项目,或者团队技术栈已深度绑定Selenium,那么继续使用Selenium也是完全可行的。

2.2 桌面应用自动化:PyAutoGUI

当你的自动化对象不是浏览器,而是电脑上的本地应用程序(如记事本、计算器、桌面客户端软件)时,Selenium和Playwright就无能为力了。这时,你需要像PyAutoGUI这样的库。

PyAutoGUI的原理是基于屏幕坐标和图像识别来控制鼠标和键盘。它不关心你操作的是什么程序,只关心屏幕上的某个像素点或某个图片区域。

  • 核心功能:移动鼠标、点击、拖拽、滚动、键盘输入、截图、在屏幕上寻找图片(图像识别)。
  • 适用场景
    1. 自动化操作没有API或标准接口的旧版桌面软件。
    2. 编写游戏外挂或宏(需注意合规性)。
    3. 跨应用程序的自动化工作流,比如从邮箱客户端保存附件,再用图片查看器打开。
  • 重大局限
    1. 脆弱性:脚本严重依赖于屏幕分辨率、窗口位置和界面视觉元素。一旦窗口被移动、界面改版或换了主题,脚本很可能失效。
    2. 速度慢:图像识别比较耗时。
    3. 无法获取元素属性:它不知道按钮的ID或文本,只能“看到”它。

实操心得:PyAutoGUI适合作为“最后的手段”,用于自动化那些无法通过其他方式(如访问控件属性)操作的软件。使用时,务必配合pyautogui.PAUSE = 1.0这样的语句在每个动作间加入暂停,给程序反应时间。更健壮的桌面自动化可以考虑pywinautowin32gui(仅Windows),它们能通过应用程序的UI控件树进行更精准的操作。

2.3 移动端自动化:Appium

当对象变成手机或平板上的App时,Appium是事实上的标准。它是一个跨平台(iOS, Android)的移动端自动化框架,其设计理念与Selenium WebDriver一脉相承,同样使用WebDriver协议。

  • 工作原理:Appium在PC上启动一个服务端,你的Python脚本作为客户端向它发送命令。Appium服务端再通过平台特有的工具(如Android的UIAutomator2, iOS的XCUITest)来驱动真机或模拟器上的App。
  • 特点:一套API可同时编写iOS和Android的测试脚本,实现了“一次编写,多端运行”的理想。
  • 学习成本:相对较高,需要配置移动开发环境(如Android SDK)、设备连接、以及理解移动端特有的概念(如Desired Capabilities)。

工具选型速查表:

工具库核心应用场景核心原理优点缺点推荐用于
SeleniumWeb浏览器自动化WebDriver协议驱动浏览器生态极好,浏览器支持全,行业标准速度较慢,需手动处理等待维护旧项目,团队技术栈统一
PlaywrightWeb浏览器自动化直接与浏览器内核通信速度快,自动等待,功能强大(网络拦截、移动模拟)生态较新,中文资料相对少新项目首选,复杂Web应用测试
PyAutoGUI桌面图形界面自动化屏幕坐标与图像识别几乎能操作任何可见的桌面程序非常脆弱,依赖视觉,速度慢无API的旧桌面软件,跨应用流程
Appium移动端App自动化WebDriver协议 + 平台原生框架跨iOS/Android,行业标准环境配置复杂,学习曲线陡移动端App的自动化测试

3. 环境搭建与核心脚本编写实战

选好了工具,接下来就是动手搭建环境并写出你的第一个自动化脚本。这里我将以目前更推荐的Playwright为例,带你走通全流程。同时,也会对比Selenium的写法,让你理解其中的差异。

3.1 环境准备:Python与Playwright安装

首先,确保你有一个可用的Python环境。如果你还没有安装Python,可以参考网络热词中的“python安装详细步骤”。这里简要说明:

  1. 访问Python官网下载安装包。
  2. 安装时,务必勾选“Add Python to PATH”,这是很多新手踩坑的地方。
  3. 安装完成后,打开命令行(CMD或Terminal),输入python --versionpython3 --version验证是否安装成功。

接下来,安装Playwright。Playwright分为两个部分:Python库和浏览器二进制文件。

# 1. 使用pip安装playwright的Python库 pip install playwright # 2. 安装Playwright所需的浏览器(Chromium, Firefox, WebKit) playwright install

playwright install这个命令会下载浏览器,可能需要一些时间,请保持网络通畅。这一步是必须的,否则脚本无法运行。

注意事项:在国内网络环境下,下载浏览器可能会很慢或失败。可以尝试设置环境变量来使用国内镜像加速,例如在命令行中先执行set PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright(Windows) 或export PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright(Mac/Linux),然后再执行playwright install

3.2 第一个脚本:打开浏览器并搜索

让我们写一个最简单的脚本:打开浏览器,访问百度,搜索一个关键词,并截图保存结果。

import asyncio from playwright.async_api import async_playwright async def main(): # 启动Playwright,管理浏览器上下文 async with async_playwright() as p: # 启动Chromium浏览器,headless=False表示显示浏览器界面 browser = await p.chromium.launch(headless=False) # 创建一个新的浏览器页面(标签页) page = await browser.new_page() # 导航到百度首页 await page.goto('https://www.baidu.com') # 定位搜索输入框,并输入关键词“Playwright” # Playwright的自动等待在这里生效:它会等待输入框出现并可交互 await page.fill('input#kw', 'Playwright') # 定位搜索按钮并点击 await page.click('input#su') # 等待页面导航到搜索结果页(网络空闲状态) await page.wait_for_load_state('networkidle') # 对搜索结果页面进行截图并保存 await page.screenshot(path='baidu_search_result.png') # 为了演示,我们等待几秒让你能看到结果 await page.wait_for_timeout(3000) # 关闭浏览器 await browser.close() # 运行异步函数 asyncio.run(main())

代码解析与避坑指南:

  1. 异步编程:Playwright推荐使用异步API(async/await)以获得最佳性能。如果你是Python异步编程的新手,只需记住用async def定义函数,在调用Playwright方法时前面加await,最后用asyncio.run()运行主函数即可。
  2. 元素定位器page.fill('input#kw', ...)中的'input#kw'是一个CSS选择器,意思是“id为kw的input元素”。这是定位元素的核心技能。你可以通过浏览器的开发者工具(F12)查看元素的ID、Class等属性来构建选择器。Playwright也提供了更强大的定位方式,如page.get_by_role("button", name="搜索"),通过角色和文本来定位,可读性更好。
  3. 自动等待:注意,我们没有写任何time.sleep或显式的WebDriverWaitpage.fillpage.click内部已经包含了等待元素可用的逻辑。page.wait_for_load_state('networkidle')是等待页面网络活动基本停止,这对于单页应用很有用。
  4. headless模式launch(headless=False)会让你看到浏览器窗口。在调试脚本时非常有用。当脚本稳定后,可以改为headless=True在后台无界面运行,节省资源且更快。

3.3 对比:用Selenium实现相同功能

为了加深理解,我们看看用Selenium如何实现同样的操作:

from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time # 1. 创建WebDriver实例,需要提前下载好chromedriver并放在PATH中 driver = webdriver.Chrome() # 或 webdriver.Firefox() 等 try: # 2. 打开百度 driver.get("https://www.baidu.com") # 3. 定位元素并输入 - 需要显式等待元素出现 wait = WebDriverWait(driver, 10) search_box = wait.until(EC.presence_of_element_located((By.ID, "kw"))) search_box.send_keys("Selenium") # 4. 点击搜索按钮 search_button = driver.find_element(By.ID, 'su') search_button.click() # 5. 等待结果加载(这里用简单粗暴的sleep,实际应用应用显式等待) time.sleep(2) # 不推荐,仅作演示 # 6. 截图 driver.save_screenshot('selenium_search_result.png') finally: # 7. 关闭浏览器 driver.quit()

Selenium与Playwright的关键差异体验:

  1. 等待机制:Selenium中,即使简单的find_element也可能因为元素未加载而抛出异常。因此,我们不得不引入WebDriverWaitexpected_conditions来构造显式等待,代码更冗长。而在Playwright中,这是内置的。
  2. 驱动管理:Selenium需要单独下载和管理浏览器驱动(如chromedriver),且驱动版本必须与浏览器版本匹配,否则会报错。这是一个常见的维护痛点。Playwright通过playwright install一站式解决了这个问题。
  3. API设计:Playwright的API设计更现代、更一致(如page.goto(),page.fill())。Selenium的API则更底层,有时需要组合多个动作。

从第一个脚本的对比就能明显感受到,Playwright在开发体验上对新手更友好,能让你更专注于业务逻辑,而非与等待和驱动问题作斗争。

4. 元素定位:UI自动化的基石与高级技巧

无论使用哪个框架,元素定位都是UI自动化最核心、也最容易出问题的环节。脚本的稳定性和可维护性,很大程度上取决于定位策略是否健壮。

4.1 基础定位策略

你需要熟练掌握以下几种定位方式,并理解其适用场景:

  1. ID定位:最优先选择。ID通常是唯一的,定位最快、最稳定。page.locator('#login-button')driver.find_element(By.ID, “login-button”)
  2. CSS选择器定位:功能最强大、最灵活的方式。可以组合标签、类、属性、层级关系进行定位。
    • 例如:input.form-control[name=’username’]定位一个name属性为username且类为form-control的输入框。
    • div.content > ul.list > li:first-child定位特定层级下的第一个li元素。
  3. XPath定位:另一种强大的定位语言,可以遍历XML/HTML文档。当元素没有ID或唯一Class时非常有用,但表达式可能较复杂且脆弱。
    • 例如://button[contains(text(), ‘提交’)]定位文本包含“提交”的按钮。
    • 慎用绝对路径:如/html/body/div[3]/div[2]/form/button,一旦页面结构微调,脚本立即失效。
  4. 文本内容定位:Playwright和现代Selenium都支持通过文本定位,这在测试中非常直观。
    • Playwright:page.get_by_text(“登录”)page.get_by_role(“button”, name=”登录”)
    • Selenium:driver.find_element(By.LINK_TEXT, “登录”)driver.find_element(By.PARTIAL_LINK_TEXT, “登录”)
  5. 属性定位:通过元素的任意属性定位。page.locator(‘[data-testid=”submit-btn”]’)。这是最佳实践之一,可以要求开发同学为关键测试元素添加唯一的># 等待元素出现在DOM中并可见 await page.locator(‘.success-message’).wait_for() # 等待元素从DOM中消失 await page.locator(‘.loading-spinner’).wait_for(state=‘hidden’) # 等待某个条件成立,如元素包含特定文本 await expect(page.locator(‘#status’)).to_have_text(‘操作成功’)
  6. Selenium的显式等待:你必须熟练掌握WebDriverWaitexpected_conditions(EC)。
    from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By wait = WebDriverWait(driver, 10) # 最多等10秒 # 等待元素可点击 element = wait.until(EC.element_to_be_clickable((By.ID, “dynamic-button”))) element.click() # 等待元素包含特定文本 wait.until(EC.text_to_be_present_in_element((By.ID, “result”), “Expected Text”))
  7. 处理iframe、Shadow DOM和新窗口:

    • iframe:你需要切换到iframe上下文才能操作其中的元素。
      # Playwright frame = page.frame_locator(‘iframe[name=”myFrame”]’) await frame.locator(‘button’).click() # 操作完后切回主页面 # Playwright的frame_locator已限定上下文,无需显式切回 # Selenium driver.switch_to.frame(“frameNameOrId”) # 操作iframe内元素... driver.switch_to.default_content() # 切回主文档
    • 新窗口/标签页:操作后需要切换上下文。
      # Playwright async with page.expect_popup() as popup_info: await page.click(‘a[target=”_blank”]’) # 点击会打开新窗口的链接 new_page = await popup_info.value await new_page.fill(‘input’, ‘data’) await new_page.close() # Selenium main_window = driver.current_window_handle driver.find_element(By.LINK_TEXT, “Open New Window”).click() # 切换到新窗口 for handle in driver.window_handles: if handle != main_window: driver.switch_to.window(handle) break # 操作新窗口... driver.close() driver.switch_to.window(main_window) # 切回原窗口

    实操心得:定位策略的“黄金法则”

    1. 优先级:唯一ID > 协商的>def test_login(): driver.get(“.../login”) driver.find_element(By.ID, “username”).send_keys(“user”) driver.find_element(By.ID, “password”).send_keys(“pass”) driver.find_element(By.ID, “submit”).click() assert “Welcome” in driver.page_source

      使用POM改造后:

      # pages/login_page.py class LoginPage: def __init__(self, driver): self.driver = driver self.username_input = (By.ID, “username”) self.password_input = (By.ID, “password”) self.submit_button = (By.ID, “submit”) def open(self): self.driver.get(“.../login”) return self def enter_credentials(self, username, password): self.driver.find_element(*self.username_input).send_keys(username) self.driver.find_element(*self.password_input).send_keys(password) return self def submit(self): self.driver.find_element(*self.submit_button).click() return HomePage(self.driver) # 返回下一个页面对象 # tests/test_login.py def test_login(): login_page = LoginPage(driver).open() home_page = login_page.enter_credentials(“user”, “pass”).submit() assert home_page.is_welcome_message_displayed()

      POM的优势:

      • 高可维护性:当登录页面的输入框ID从“username”改为“user-name”时,你只需要在LoginPage类中修改一处。
      • 高可读性:测试用例读起来就像自然语言,清晰地描述了“打开登录页 -> 输入凭证 -> 提交 -> 验证欢迎信息”的业务流程。
      • 低冗余:公共操作被封装,避免在多个测试用例中重复编写相同的定位和操作代码。

      5.2 数据驱动测试:让用例更灵活

      将测试数据(如用户名、密码、搜索关键词)从脚本中分离出来,存储在外部文件(如JSON、YAML、Excel、CSV)或数据库中。这样,同一套脚本逻辑可以用多组数据进行测试。

      import pytest import json # 从JSON文件加载测试数据 with open(‘test_data/login_data.json’) as f: test_data = json.load(f) @pytest.mark.parametrize(“data”, test_data) def test_login_with_multiple_users(login_page, data): home_page = login_page.open().enter_credentials(data[‘username’], data[‘password’]).submit() if data[‘should_succeed’]: assert home_page.is_welcome_message_displayed() else: assert login_page.is_error_message_displayed(data[‘expected_error’])

      通过pytest@parametrize装饰器,可以轻松实现数据驱动,极大地扩展了测试覆盖范围。

      5.3 测试报告与日志:让结果一目了然

      脚本运行后,你需要知道它成功了还是失败了,如果失败了,失败在哪里。清晰的报告和日志至关重要。

      • Allure报告:生成非常美观、交互式的HTML测试报告,可以展示测试步骤、截图、错误日志等,是呈现给团队和领导的最佳选择。
      • HTMLTestRunner / pytest-html:生成简单的HTML报告,配置快速。
      • 日志模块:使用Python内置的logging模块,在关键步骤(如开始操作、完成操作、遇到异常)记录信息到文件和控制台。
        import logging logging.basicConfig(level=logging.INFO, format=‘%(asctime)s - %(levelname)s - %(message)s’) logger = logging.getLogger(__name__) def click_element(locator): logger.info(f”Attempting to click element: {locator}”) try: element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable(locator)) element.click() logger.info(“Click successful.”) except TimeoutException: logger.error(f”Failed to click element {locator}. Screenshot saved.”) driver.save_screenshot(“error.png”) raise

      5.4 持续集成:让自动化真正“跑起来”

      自动化脚本不应该只在本地手动运行。将其集成到持续集成/持续部署流水线中(如Jenkins, GitLab CI, GitHub Actions),才能发挥最大价值。

      • 触发时机:代码提交后、每日定时、版本发布前。
      • 关键配置
        1. 无头模式:CI服务器通常没有图形界面,必须使用headless=True
        2. 依赖安装:在CI任务中,需要安装Python依赖(pip install -r requirements.txt)和Playwright浏览器(playwright install --with-deps)。
        3. 测试执行:运行测试命令,如pytest tests/ --alluredir=./allure-results
        4. 结果收集:将测试报告(如Allure报告)归档并发布到CI界面,方便查看。
        5. 失败通知:配置当测试失败时,通过邮件、钉钉、Slack等通知相关负责人。

      一个简单的GitHub Actions工作流示例(.github/workflows/ui-test.yml):

      name: UI Automation Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: ‘3.10’ - name: Install dependencies run: | pip install -r requirements.txt playwright install --with-deps chromium - name: Run tests with pytest run: | pytest tests/ -v --html=report.html --self-contained-html - name: Upload test report uses: actions/upload-artifact@v3 if: always() with: name: ui-test-report path: report.html

      6. 常见问题排查与实战避坑指南

      即使掌握了所有技术,在实际编写和运行UI自动化脚本时,你依然会遇到各种各样的问题。下面是我从多年实战中总结出的最常见问题及其解决方案。

      6.1 “元素找不到”或“元素不可交互”

      这是排名第一的错误。

      • 可能原因及解决
        1. 页面未加载完成使用智能等待,永远不要用time.sleep确保在操作前,元素已经处于可交互状态(Playwright自动处理,Selenium用EC.element_to_be_clickable)。
        2. iframe/Shadow DOM:你操作的元素在iframe或Shadow DOM内部,需要先切换到正确的上下文。
        3. 元素被遮挡:可能有弹窗、悬浮层盖住了目标元素。尝试先关闭或处理这些遮挡物。
        4. 定位器不稳定:使用的CSS或XPath表达式可能因为页面动态变化而失效。优先使用唯一ID或与开发约定的># Playwright browser = await p.chromium.launch(timeout=60000) # 60秒 page.set_default_timeout(30000) # 页面操作超时30秒 # Selenium driver.implicitly_wait(30) # 隐式等待(慎用,不如显式等待)

      6.3 如何处理验证码、滑块等反自动化机制?

      这是一个棘手但常见的问题。完全自动化解开复杂的验证码(如扭曲文字、点选)在法律和技术上都有挑战。以下是务实的应对策略:

      1. 测试环境绕过:与开发团队沟通,在测试环境中禁用验证码,或提供“万能验证码”(如输入“0000”即可通过)。这是最推荐、最高效的方式。
      2. 临时手动干预:对于偶尔运行的脚本,可以在遇到验证码时暂停脚本,弹出提示让手动输入,然后脚本继续。可以使用input(“请输入验证码:”)来实现。
      3. 第三方服务:对于必须处理的情况,可以考虑付费的验证码识别服务(OCR API),但需评估成本和稳定性。
      4. Cookie/Session复用:如果自动化流程的目的是登录后的操作,可以尝试先手动登录一次,保存浏览器的Cookie或Session状态,然后在自动化脚本中加载使用,跳过登录环节。

      6.4 如何提升脚本的执行速度?

      1. 并发执行:使用pytest-xdist插件可以并行运行多个测试用例,充分利用多核CPU。
      2. 减少不必要的等待:优化等待条件,使用更精准的等待(如等待特定元素出现,而非固定sleep)。Playwright的自动等待本身已优于Selenium的固定等待。
      3. 复用浏览器上下文:对于一组相关的测试,不要每个测试都启动和关闭浏览器。可以使用pytestfixture设置scope=”session””module”,让多个测试共享同一个浏览器实例。
        import pytest from playwright.sync_api import sync_playwright @pytest.fixture(scope=”session”) def browser(): with sync_playwright() as p: browser = p.chromium.launch(headless=True) yield browser browser.close() @pytest.fixture def page(browser): context = browser.new_context() page = context.new_page() yield page context.close()
      4. 选择更快的框架:如前所述,Playwright在无头模式下的执行速度通常快于Selenium。

      6.5 脚本的维护成本如何控制?

      UI自动化脚本因其对前端变化的敏感性而被称为“脆弱的测试”。控制维护成本是关键。

      1. 推行“测试友好”开发:这是治本之策。推动前端开发同学为关键交互元素添加稳定的测试属性(如>

最新新闻

日新闻

周新闻

月新闻