1. 项目概述为什么选择AirtestSelenium组合拳如果你刚接触自动化测试面对一堆工具名词可能有点懵Selenium我知道是Web自动化的老大哥那Airtest又是什么为什么要把它们俩放一起这恰恰是这个方案的精妙之处。我最初接触自动化时也走过弯路要么用纯Selenium写脚本调试起来像在走钢丝一个元素定位失败就全盘卡住要么用一些录制工具生成的代码像天书维护成本极高。直到我发现了Airtest-Selenium这个“缝合怪”才感觉找到了新手和老手都能上手的平衡点。简单来说Airtest是一个由网易开源的、基于图像识别的自动化测试框架它的核心优势是“所见即所得”——你不用太关心网页背后复杂的HTML结构直接对屏幕上看到的按钮、输入框截图它就能帮你点进去、输入文字。这对0基础的朋友极其友好大大降低了门槛。而Selenium则是Web自动化领域的标准它通过直接操作浏览器驱动能精准地控制网页元素执行复杂的逻辑判断是自动化测试稳定性和深度的保证。把它们结合起来就像是给汽车装上了自动驾驶Airtest的图像识别和手动驾驶Selenium的代码控制两套系统你可以根据路况随时切换既保证了易用性又不失灵活性。这次我们以Firefox浏览器为目标一是因为它对WebDriver协议支持非常标准环境配置相对简单二是在某些特定场景如测试浏览器插件、兼容性测试下Firefox是必不可少的。这个教程的目标就是让你在完全不懂代码的情况下也能搭建起环境并成功运行第一个自动化测试脚本感受“机器帮你点点点”的魔力。2. 环境搭建与工具安装从零开始的避坑指南万事开头难自动化测试的第一步——环境搭建就劝退了不少人。网上教程很多但版本冲突、路径问题、驱动不对应等坑一个接一个。下面我结合自己踩过的所有坑给你梳理一条最清晰的路径。我们的核心是安装三个东西Python、Airtest-Selenium库、Firefox浏览器及其驱动。2.1 Python环境安装与配置Python是我们的脚本运行环境。别怕安装它比装一个游戏还简单。下载安装直接访问Python官网下载最新的稳定版比如3.10或3.11。安装时务必勾选“Add Python to PATH”这个选项。这是最重要的一步勾选后系统才能识别python命令。很多新手卡住就是因为没勾这个。验证安装安装完成后打开命令行Windows按WinR输入cmdMac打开终端。输入python --version并回车。如果显示类似“Python 3.10.0”的版本号恭喜你第一步成功了。如果提示“不是内部或外部命令”那就需要手动添加环境变量具体路径在你安装Python的目录下。注意不建议安装太新的Python版本如3.12因为一些库的兼容性可能还没跟上。选择3.8-3.11之间的版本最为稳妥。2.2 安装Airtest-Selenium与Selenium库有了Python安装库就一行命令的事。但这里有个关键点我们不是安装airtest而是安装airtest-selenium。它封装了Selenium并加入了Airtest的图像识别能力。继续在刚才的命令行里输入以下命令pip install airtest-selenium这条命令会自动安装airtest-selenium以及它所依赖的selenium库。pip是Python的包管理工具安装时可能会因为网络问题慢或失败可以尝试在后面加上-i https://pypi.tuna.tsinghua.edu.cn/simple来使用国内镜像加速。安装完成后可以输入pip list查看已安装的包确认能看到airtest-selenium和selenium。2.3 Firefox浏览器与GeckoDriver驱动部署这是最容易出错的一步。Selenium控制浏览器需要一个“翻译官”这就是浏览器驱动Driver。安装Firefox浏览器如果你没有去Mozilla官网下载并安装最新稳定版的Firefox。记住它的安装位置通常不需要特别记住但知道没坏处。下载GeckoDriver这是Firefox的驱动。前往GeckoDriver的GitHub发布页。关键来了驱动版本必须和你的Firefox浏览器大版本号匹配比如你安装了Firefox 115就去找支持Firefox 115的GeckoDriver版本。下载对应你操作系统的文件Windows是.zipMac是.tar.gz。配置GeckoDriver简单方法推荐给新手将下载解压后得到的geckodriver.exeWindows或geckodriverMac/Linux文件直接扔到Python的安装目录下和python.exe在同一文件夹。因为Python安装目录通常已在系统PATH中这样Selenium就能自动找到它。标准方法将geckodriver所在目录的路径添加到系统的环境变量PATH中。具体操作可以搜索“如何添加环境变量”不同系统略有不同。验证驱动是否可用打开命令行输入geckodriver --version。如果能看到版本信息输出说明驱动配置成功。如果提示命令找不到请检查上述路径配置。3. 第一个脚本从图像识别开始感受自动化环境齐备我们来写第一个真正意义上的自动化脚本。这个脚本的目标是打开百度首页在搜索框输入“自动化测试”然后点击搜索按钮。我们将先用Airtest最核心的图像识别功能来实现让你直观感受它的便利。创建一个新的文本文件将其后缀改为.py例如first_test.py。用任何文本编辑器推荐VSCode、Sublime Text甚至记事本打开它输入以下代码from airtest_selenium.proxy import WebFirefox from airtest.core.api import * # 1. 创建一个WebFirefox对象这会启动Firefox浏览器 driver WebFirefox() # 2. 设置浏览器窗口最大化并访问百度 driver.maximize_window() driver.get(https://www.baidu.com) # 3. 使用Airtest的图像识别功能定位搜索框并输入文字 # touch()函数用于点击或定位图片。这里我们传入一张搜索框的截图。 # 你需要先对百度首页的搜索框进行截图保存为“search_box.png”并放在与脚本同目录下。 touch(Template(rsearch_box.png)) # 在定位到的位置输入文字 text(自动化测试) # 4. 同样对“百度一下”按钮截图保存为“search_button.png”并点击 touch(Template(rsearch_button.png)) # 5. 等待几秒看看搜索结果页面 sleep(5) # 6. 关闭浏览器 driver.quit()代码解读与实操要点WebFirefox()这是airtest-selenium提供的类它初始化了一个同时支持Selenium操作和Airtest图像识别的Firefox浏览器对象。driver.get()这是标准的Selenium方法用于跳转到指定网址。touch(Template(...))这是Airtest的“灵魂”。Template对象封装了一张图片。touch命令会在当前屏幕上寻找与这张图片最匹配的区域然后执行点击操作。如果只是定位像搜索框那样它会把光标移过去。text()在当前位置输入文本。关键步骤——截图运行上述脚本前先手动打开Firefox访问www.baidu.com。使用系统自带的截图工具如Windows的Snipping Tool精确地截取搜索框的区域尽量只包含输入框本身背景干净。保存为search_box.png放在你的Python脚本同一个文件夹里。同样截取“百度一下”按钮保存为search_button.png。运行脚本在命令行中切换到你的脚本所在目录输入python first_test.py。你会看到Firefox自动打开访问百度自动在搜索框输入文字并点击搜索。整个过程我们一行HTML代码都没分析全靠“看图操作”。实操心得图像识别的优势是直观、抗前端微小改动比如CSS样式变了但按钮样子没变。但它的缺点是速度相对慢一点且受屏幕分辨率、缩放比例影响。截图时务必保证运行脚本时的浏览器状态页面缩放比例、窗口大小与截图时尽量一致。4. 深入Selenium元素定位与稳健操作纯靠图像识别遇到复杂逻辑或需要获取页面数据时就力不从心了。这时就需要祭出Selenium的看家本领——元素定位。Selenium提供了多达8种定位元素的方法我们掌握最常用的3-4种就足以应对90%的场景。让我们改造上面的脚本用Selenium的方式实现同样的功能from airtest_selenium.proxy import WebFirefox from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys import time driver WebFirefox() driver.maximize_window() driver.get(https://www.baidu.com) # 方法1通过ID定位。查看百度首页搜索框的HTML会发现它有 idkw search_box driver.find_element(By.ID, kw) # 找到元素后清空防止有默认文本然后输入内容 search_box.clear() search_box.send_keys(自动化测试) # 方法2通过CSS_SELECTOR定位“百度一下”按钮。它的id是“su” search_button driver.find_element(By.CSS_SELECTOR, #su) search_button.click() # 或者方法3在搜索框输入后直接按回车键无需定位按钮 # search_box.send_keys(Keys.RETURN) time.sleep(5) driver.quit()元素定位方法详解By.ID通过HTML元素的id属性定位。id通常是唯一的定位速度最快首选。By.NAME通过name属性定位。By.CLASS_NAME通过class属性定位。注意一个元素可能有多个class。By.CSS_SELECTOR通过CSS选择器定位功能非常强大灵活。#su表示选择idsu的元素。By.XPATH通过XML路径定位功能最强大但也最复杂可以在没有id、class时使用但性能稍差。如何查看元素属性 在浏览器页面按F12打开开发者工具点击左上角的箭头图标然后去点击页面上的元素如搜索框开发者工具就会自动定位到对应的HTML代码里面就能看到id、class、name等属性。注意事项find_element只返回找到的第一个匹配元素。如果页面上有多个相同特征的元素请使用find_elements返回列表或更精确的选择器。元素定位是自动化测试稳定的基石定位不准后续所有操作都会失败。5. 混合模式实战图像识别与代码控制的完美配合纯粹的图像识别或纯粹的代码控制都不是最优解。真正的效率来自于“混合模式”在常规流程中用稳定的Selenium代码在那些难以定位、动态变化或者需要视觉确认的地方用Airtest的图像识别来辅助。场景测试一个购物网站需要登录。登录按钮很容易用By.ID定位。但登录后页面上可能会弹出一个随机的、非HTML元素构成的图形验证码或者一个动态的欢迎提示浮层。这时Selenium就无能为力了。混合模式脚本示例from airtest_selenium.proxy import WebFirefox from selenium.webdriver.common.by import By from airtest.core.api import * import time driver WebFirefox() driver.get(你的购物网站登录页URL) # --- 第一部分使用Selenium完成稳定操作 --- # 定位用户名、密码输入框并输入 username driver.find_element(By.ID, username) password driver.find_element(By.ID, password) username.send_keys(your_username) password.send_keys(your_password) # 定位并点击登录按钮假设是标准HTML按钮 login_button driver.find_element(By.CSS_SELECTOR, .login-btn) login_button.click() time.sleep(2) # 等待页面跳转或弹窗出现 # --- 第二部分使用Airtest处理非标准或动态内容 --- # 情况1处理图形验证码弹窗假设弹窗关闭按钮是张图片 try: # 尝试用Selenium定位关闭按钮如果找不到可能是图片则捕获异常 close_btn driver.find_element(By.CLASS_NAME, close-modal) close_btn.click() except: # 使用Airtest图像识别来点击关闭按钮的截图 # 你需要事先截好弹窗关闭按钮的图保存为 close_popup.png touch(Template(rclose_popup.png)) print(使用图像识别关闭了弹窗。) # 情况2登录成功后需要视觉确认某个元素如用户头像出现 # 截图保存用户头像区域为 avatar.png if exists(Template(ravatar.png)): print(登录成功用户头像已显示) else: print(登录可能失败未检测到头像。) # 可以在这里加入失败处理逻辑比如截图保存错误现场 driver.save_screenshot(login_failed.png) # --- 继续后续的Selenium自动化操作 --- # 例如去搜索商品 search_input driver.find_element(By.ID, search) search_input.send_keys(手机) search_input.submit() time.sleep(3) driver.quit()混合模式的优势稳定性核心流程输入、点击标准按钮用Selenium不受UI样式微小变化影响。灵活性应对弹窗、验证码、Flash组件等“代码盲区”时图像识别是最后的保障。可维护性大部分逻辑是结构化的代码易于阅读和修改。图像识别作为补充只在必要时使用。实操心得在项目中我会为常见的非标准弹窗、广告位、验证码区域建立专门的“图片库”。当Selenium脚本运行失败时会触发一个“图像救援”流程尝试用预存的图片去识别并处理这些干扰项。这大大提高了自动化脚本的健壮性。6. 核心技巧与最佳实践让你的脚本更健壮写一个能跑的脚本不难写一个能在各种环境下稳定运行的脚本才是本事。下面这些技巧是我在无数个调试的夜晚总结出来的。6.1 智能等待告别sleep的笨办法新手最爱用time.sleep(10)这是万恶之源。网络慢一点、电脑卡一点10秒可能不够网络快10秒又纯属浪费。Selenium提供了两种智能等待隐式等待driver.implicitly_wait(10)。设置后在查找任何元素时如果立即没找到WebDriver会轮询DOM最多10秒一旦找到就继续。这是一个全局设置。显式等待更精确、更推荐。它可以等待某个特定条件成立如元素可见、可点击、包含特定文本。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待“百度一下”按钮可见并可点击最多等10秒 wait WebDriverWait(driver, 10) search_button wait.until(EC.element_to_be_clickable((By.ID, su))) search_button.click()最佳实践在脚本开头设置一个较短的隐式等待如5秒作为安全网。在关键操作如点击一个需要加载的按钮后跳转前使用显式等待条件更精确。6.2 异常处理与日志记录脚本不可能永远成功。网络中断、元素变更、页面加载超时都会导致失败。好的脚本要能“优雅地失败”并告诉你为什么。import logging from selenium.common.exceptions import NoSuchElementException, TimeoutException logging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s) try: element driver.find_element(By.ID, nonExistentId) element.click() except NoSuchElementException: logging.error(未找到ID为nonExistentId的元素页面结构可能已变更。) driver.save_screenshot(error_screenshot.png) # 保存现场截图 except TimeoutException: logging.warning(操作超时请检查网络或服务器状态。) except Exception as e: logging.critical(f发生未知错误: {e}) finally: # 无论成功失败最后都尝试关闭浏览器 if driver: driver.quit()6.3 页面对象模型POM设计模式初探当测试用例越来越多你会发现同样的元素定位代码散落在各个脚本里一旦页面改了一个id你需要修改所有脚本。POM就是为了解决这个问题将页面元素定位和页面操作封装成单独的类。# 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.login_button (By.CSS_SELECTOR, .login-btn) def enter_username(self, username): self.driver.find_element(*self.username_input).send_keys(username) def enter_password(self, password): self.driver.find_element(*self.password_input).send_keys(password) def click_login(self): self.driver.find_element(*self.login_button).click() # 在你的测试脚本中 from login_page import LoginPage driver WebFirefox() login_page LoginPage(driver) driver.get(登录页URL) login_page.enter_username(test_user) login_page.enter_password(test_pass) login_page.click_login()这样做的好处是如果登录页面的id变了你只需要修改LoginPage这个类里的一个地方所有用到这个页面的测试脚本都自动生效。这是迈向编写可维护、大型自动化测试套件的重要一步。7. 常见问题排查与调试技巧实录即使按照教程一步步来你也可能会遇到问题。下面是我整理的“故障排除清单”覆盖了90%的常见错误。问题现象可能原因解决方案WebDriverException: Message: ‘geckodriver’ executable needs to be in PATH.系统找不到GeckoDriver驱动。1. 确认geckodriver文件已下载。2. 确认其所在目录已添加到系统环境变量PATH中或将其放在Python安装目录下。3. 重启命令行终端。SessionNotCreatedException: Unable to find a matching set of capabilities浏览器版本与驱动版本不匹配。检查Firefox浏览器版本下载对应大版本号的GeckoDriver。去GeckoDriver官网查看版本支持表。NoSuchElementException: Unable to locate element元素定位失败。1.检查定位器用F12开发者工具确认元素的id/class/selector是否正确注意是否在iframe内。2.检查时机元素是否还没加载出来在find_element前加入time.sleep或显式等待。3.检查唯一性定位器是否匹配了多个元素find_element只取第一个。ElementNotInteractableException: Element is not clickable at point元素不可交互。1. 元素被遮挡如弹窗。关闭遮挡物。2. 元素在视窗外。使用driver.execute_script(“arguments[0].scrollIntoView();”, element)滚动到元素位置。3. 元素状态为disabled。检查业务逻辑。Airtest的touch()命令报错TargetNotFoundError未在屏幕上找到匹配的图片。1.截图问题截图是否准确背景是否太杂乱运行脚本时浏览器窗口位置、大小、页面缩放比例是否与截图时完全一致2.阈值问题Template可以设置threshold匹配阈值默认0.8。如果画面有微小变化尝试降低阈值如Template(r”img.png”, threshold0.7)。3. 使用exists()函数先判断图片是否存在再进行操作。脚本在IDE里运行正常在命令行运行失败环境变量或当前工作目录问题。1. 确保在命令行中当前目录是你的脚本所在目录尤其是涉及图片路径时。2. 检查命令行中Python和pip的版本是否与IDE中使用的一致。Firefox启动后马上闪退可能是浏览器驱动与浏览器版本严重不兼容或存在多个Firefox实例冲突。1. 彻底关闭所有Firefox进程在任务管理器中结束firefox.exe。2. 使用driver WebFirefox(firefox_binary’Firefox可执行文件路径’)显式指定浏览器位置。调试技巧多用screenshot在关键步骤前后特别是失败前使用driver.save_screenshot(“step1.png”)保存截图能帮你直观看到当时的页面状态。打印信息多用print()输出当前URL、元素属性等信息。手动复现遇到问题时尝试手动操作一遍观察页面是否有异步加载、弹窗、重定向等意外行为。降低速度在开发调试阶段可以在操作之间加入time.sleep(1)让你能看清自动化过程便于定位问题。走到这里你已经从一个对自动化测试一无所知的新手变成了一个能够搭建环境、编写混合模式脚本、并具备基本排查能力的实践者。这套Airtest-Selenium的组合为你打开了一扇门。接下来你可以尝试用它们去自动化你日常工作中那些重复的网页操作比如数据抓取、报表生成、定期巡检等。记住所有复杂的自动化项目都是由一个个像“打开百度并搜索”这样的小脚本组合而成的。
Airtest+Selenium自动化测试实战:从零搭建混合模式脚本
1. 项目概述为什么选择AirtestSelenium组合拳如果你刚接触自动化测试面对一堆工具名词可能有点懵Selenium我知道是Web自动化的老大哥那Airtest又是什么为什么要把它们俩放一起这恰恰是这个方案的精妙之处。我最初接触自动化时也走过弯路要么用纯Selenium写脚本调试起来像在走钢丝一个元素定位失败就全盘卡住要么用一些录制工具生成的代码像天书维护成本极高。直到我发现了Airtest-Selenium这个“缝合怪”才感觉找到了新手和老手都能上手的平衡点。简单来说Airtest是一个由网易开源的、基于图像识别的自动化测试框架它的核心优势是“所见即所得”——你不用太关心网页背后复杂的HTML结构直接对屏幕上看到的按钮、输入框截图它就能帮你点进去、输入文字。这对0基础的朋友极其友好大大降低了门槛。而Selenium则是Web自动化领域的标准它通过直接操作浏览器驱动能精准地控制网页元素执行复杂的逻辑判断是自动化测试稳定性和深度的保证。把它们结合起来就像是给汽车装上了自动驾驶Airtest的图像识别和手动驾驶Selenium的代码控制两套系统你可以根据路况随时切换既保证了易用性又不失灵活性。这次我们以Firefox浏览器为目标一是因为它对WebDriver协议支持非常标准环境配置相对简单二是在某些特定场景如测试浏览器插件、兼容性测试下Firefox是必不可少的。这个教程的目标就是让你在完全不懂代码的情况下也能搭建起环境并成功运行第一个自动化测试脚本感受“机器帮你点点点”的魔力。2. 环境搭建与工具安装从零开始的避坑指南万事开头难自动化测试的第一步——环境搭建就劝退了不少人。网上教程很多但版本冲突、路径问题、驱动不对应等坑一个接一个。下面我结合自己踩过的所有坑给你梳理一条最清晰的路径。我们的核心是安装三个东西Python、Airtest-Selenium库、Firefox浏览器及其驱动。2.1 Python环境安装与配置Python是我们的脚本运行环境。别怕安装它比装一个游戏还简单。下载安装直接访问Python官网下载最新的稳定版比如3.10或3.11。安装时务必勾选“Add Python to PATH”这个选项。这是最重要的一步勾选后系统才能识别python命令。很多新手卡住就是因为没勾这个。验证安装安装完成后打开命令行Windows按WinR输入cmdMac打开终端。输入python --version并回车。如果显示类似“Python 3.10.0”的版本号恭喜你第一步成功了。如果提示“不是内部或外部命令”那就需要手动添加环境变量具体路径在你安装Python的目录下。注意不建议安装太新的Python版本如3.12因为一些库的兼容性可能还没跟上。选择3.8-3.11之间的版本最为稳妥。2.2 安装Airtest-Selenium与Selenium库有了Python安装库就一行命令的事。但这里有个关键点我们不是安装airtest而是安装airtest-selenium。它封装了Selenium并加入了Airtest的图像识别能力。继续在刚才的命令行里输入以下命令pip install airtest-selenium这条命令会自动安装airtest-selenium以及它所依赖的selenium库。pip是Python的包管理工具安装时可能会因为网络问题慢或失败可以尝试在后面加上-i https://pypi.tuna.tsinghua.edu.cn/simple来使用国内镜像加速。安装完成后可以输入pip list查看已安装的包确认能看到airtest-selenium和selenium。2.3 Firefox浏览器与GeckoDriver驱动部署这是最容易出错的一步。Selenium控制浏览器需要一个“翻译官”这就是浏览器驱动Driver。安装Firefox浏览器如果你没有去Mozilla官网下载并安装最新稳定版的Firefox。记住它的安装位置通常不需要特别记住但知道没坏处。下载GeckoDriver这是Firefox的驱动。前往GeckoDriver的GitHub发布页。关键来了驱动版本必须和你的Firefox浏览器大版本号匹配比如你安装了Firefox 115就去找支持Firefox 115的GeckoDriver版本。下载对应你操作系统的文件Windows是.zipMac是.tar.gz。配置GeckoDriver简单方法推荐给新手将下载解压后得到的geckodriver.exeWindows或geckodriverMac/Linux文件直接扔到Python的安装目录下和python.exe在同一文件夹。因为Python安装目录通常已在系统PATH中这样Selenium就能自动找到它。标准方法将geckodriver所在目录的路径添加到系统的环境变量PATH中。具体操作可以搜索“如何添加环境变量”不同系统略有不同。验证驱动是否可用打开命令行输入geckodriver --version。如果能看到版本信息输出说明驱动配置成功。如果提示命令找不到请检查上述路径配置。3. 第一个脚本从图像识别开始感受自动化环境齐备我们来写第一个真正意义上的自动化脚本。这个脚本的目标是打开百度首页在搜索框输入“自动化测试”然后点击搜索按钮。我们将先用Airtest最核心的图像识别功能来实现让你直观感受它的便利。创建一个新的文本文件将其后缀改为.py例如first_test.py。用任何文本编辑器推荐VSCode、Sublime Text甚至记事本打开它输入以下代码from airtest_selenium.proxy import WebFirefox from airtest.core.api import * # 1. 创建一个WebFirefox对象这会启动Firefox浏览器 driver WebFirefox() # 2. 设置浏览器窗口最大化并访问百度 driver.maximize_window() driver.get(https://www.baidu.com) # 3. 使用Airtest的图像识别功能定位搜索框并输入文字 # touch()函数用于点击或定位图片。这里我们传入一张搜索框的截图。 # 你需要先对百度首页的搜索框进行截图保存为“search_box.png”并放在与脚本同目录下。 touch(Template(rsearch_box.png)) # 在定位到的位置输入文字 text(自动化测试) # 4. 同样对“百度一下”按钮截图保存为“search_button.png”并点击 touch(Template(rsearch_button.png)) # 5. 等待几秒看看搜索结果页面 sleep(5) # 6. 关闭浏览器 driver.quit()代码解读与实操要点WebFirefox()这是airtest-selenium提供的类它初始化了一个同时支持Selenium操作和Airtest图像识别的Firefox浏览器对象。driver.get()这是标准的Selenium方法用于跳转到指定网址。touch(Template(...))这是Airtest的“灵魂”。Template对象封装了一张图片。touch命令会在当前屏幕上寻找与这张图片最匹配的区域然后执行点击操作。如果只是定位像搜索框那样它会把光标移过去。text()在当前位置输入文本。关键步骤——截图运行上述脚本前先手动打开Firefox访问www.baidu.com。使用系统自带的截图工具如Windows的Snipping Tool精确地截取搜索框的区域尽量只包含输入框本身背景干净。保存为search_box.png放在你的Python脚本同一个文件夹里。同样截取“百度一下”按钮保存为search_button.png。运行脚本在命令行中切换到你的脚本所在目录输入python first_test.py。你会看到Firefox自动打开访问百度自动在搜索框输入文字并点击搜索。整个过程我们一行HTML代码都没分析全靠“看图操作”。实操心得图像识别的优势是直观、抗前端微小改动比如CSS样式变了但按钮样子没变。但它的缺点是速度相对慢一点且受屏幕分辨率、缩放比例影响。截图时务必保证运行脚本时的浏览器状态页面缩放比例、窗口大小与截图时尽量一致。4. 深入Selenium元素定位与稳健操作纯靠图像识别遇到复杂逻辑或需要获取页面数据时就力不从心了。这时就需要祭出Selenium的看家本领——元素定位。Selenium提供了多达8种定位元素的方法我们掌握最常用的3-4种就足以应对90%的场景。让我们改造上面的脚本用Selenium的方式实现同样的功能from airtest_selenium.proxy import WebFirefox from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys import time driver WebFirefox() driver.maximize_window() driver.get(https://www.baidu.com) # 方法1通过ID定位。查看百度首页搜索框的HTML会发现它有 idkw search_box driver.find_element(By.ID, kw) # 找到元素后清空防止有默认文本然后输入内容 search_box.clear() search_box.send_keys(自动化测试) # 方法2通过CSS_SELECTOR定位“百度一下”按钮。它的id是“su” search_button driver.find_element(By.CSS_SELECTOR, #su) search_button.click() # 或者方法3在搜索框输入后直接按回车键无需定位按钮 # search_box.send_keys(Keys.RETURN) time.sleep(5) driver.quit()元素定位方法详解By.ID通过HTML元素的id属性定位。id通常是唯一的定位速度最快首选。By.NAME通过name属性定位。By.CLASS_NAME通过class属性定位。注意一个元素可能有多个class。By.CSS_SELECTOR通过CSS选择器定位功能非常强大灵活。#su表示选择idsu的元素。By.XPATH通过XML路径定位功能最强大但也最复杂可以在没有id、class时使用但性能稍差。如何查看元素属性 在浏览器页面按F12打开开发者工具点击左上角的箭头图标然后去点击页面上的元素如搜索框开发者工具就会自动定位到对应的HTML代码里面就能看到id、class、name等属性。注意事项find_element只返回找到的第一个匹配元素。如果页面上有多个相同特征的元素请使用find_elements返回列表或更精确的选择器。元素定位是自动化测试稳定的基石定位不准后续所有操作都会失败。5. 混合模式实战图像识别与代码控制的完美配合纯粹的图像识别或纯粹的代码控制都不是最优解。真正的效率来自于“混合模式”在常规流程中用稳定的Selenium代码在那些难以定位、动态变化或者需要视觉确认的地方用Airtest的图像识别来辅助。场景测试一个购物网站需要登录。登录按钮很容易用By.ID定位。但登录后页面上可能会弹出一个随机的、非HTML元素构成的图形验证码或者一个动态的欢迎提示浮层。这时Selenium就无能为力了。混合模式脚本示例from airtest_selenium.proxy import WebFirefox from selenium.webdriver.common.by import By from airtest.core.api import * import time driver WebFirefox() driver.get(你的购物网站登录页URL) # --- 第一部分使用Selenium完成稳定操作 --- # 定位用户名、密码输入框并输入 username driver.find_element(By.ID, username) password driver.find_element(By.ID, password) username.send_keys(your_username) password.send_keys(your_password) # 定位并点击登录按钮假设是标准HTML按钮 login_button driver.find_element(By.CSS_SELECTOR, .login-btn) login_button.click() time.sleep(2) # 等待页面跳转或弹窗出现 # --- 第二部分使用Airtest处理非标准或动态内容 --- # 情况1处理图形验证码弹窗假设弹窗关闭按钮是张图片 try: # 尝试用Selenium定位关闭按钮如果找不到可能是图片则捕获异常 close_btn driver.find_element(By.CLASS_NAME, close-modal) close_btn.click() except: # 使用Airtest图像识别来点击关闭按钮的截图 # 你需要事先截好弹窗关闭按钮的图保存为 close_popup.png touch(Template(rclose_popup.png)) print(使用图像识别关闭了弹窗。) # 情况2登录成功后需要视觉确认某个元素如用户头像出现 # 截图保存用户头像区域为 avatar.png if exists(Template(ravatar.png)): print(登录成功用户头像已显示) else: print(登录可能失败未检测到头像。) # 可以在这里加入失败处理逻辑比如截图保存错误现场 driver.save_screenshot(login_failed.png) # --- 继续后续的Selenium自动化操作 --- # 例如去搜索商品 search_input driver.find_element(By.ID, search) search_input.send_keys(手机) search_input.submit() time.sleep(3) driver.quit()混合模式的优势稳定性核心流程输入、点击标准按钮用Selenium不受UI样式微小变化影响。灵活性应对弹窗、验证码、Flash组件等“代码盲区”时图像识别是最后的保障。可维护性大部分逻辑是结构化的代码易于阅读和修改。图像识别作为补充只在必要时使用。实操心得在项目中我会为常见的非标准弹窗、广告位、验证码区域建立专门的“图片库”。当Selenium脚本运行失败时会触发一个“图像救援”流程尝试用预存的图片去识别并处理这些干扰项。这大大提高了自动化脚本的健壮性。6. 核心技巧与最佳实践让你的脚本更健壮写一个能跑的脚本不难写一个能在各种环境下稳定运行的脚本才是本事。下面这些技巧是我在无数个调试的夜晚总结出来的。6.1 智能等待告别sleep的笨办法新手最爱用time.sleep(10)这是万恶之源。网络慢一点、电脑卡一点10秒可能不够网络快10秒又纯属浪费。Selenium提供了两种智能等待隐式等待driver.implicitly_wait(10)。设置后在查找任何元素时如果立即没找到WebDriver会轮询DOM最多10秒一旦找到就继续。这是一个全局设置。显式等待更精确、更推荐。它可以等待某个特定条件成立如元素可见、可点击、包含特定文本。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待“百度一下”按钮可见并可点击最多等10秒 wait WebDriverWait(driver, 10) search_button wait.until(EC.element_to_be_clickable((By.ID, su))) search_button.click()最佳实践在脚本开头设置一个较短的隐式等待如5秒作为安全网。在关键操作如点击一个需要加载的按钮后跳转前使用显式等待条件更精确。6.2 异常处理与日志记录脚本不可能永远成功。网络中断、元素变更、页面加载超时都会导致失败。好的脚本要能“优雅地失败”并告诉你为什么。import logging from selenium.common.exceptions import NoSuchElementException, TimeoutException logging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s) try: element driver.find_element(By.ID, nonExistentId) element.click() except NoSuchElementException: logging.error(未找到ID为nonExistentId的元素页面结构可能已变更。) driver.save_screenshot(error_screenshot.png) # 保存现场截图 except TimeoutException: logging.warning(操作超时请检查网络或服务器状态。) except Exception as e: logging.critical(f发生未知错误: {e}) finally: # 无论成功失败最后都尝试关闭浏览器 if driver: driver.quit()6.3 页面对象模型POM设计模式初探当测试用例越来越多你会发现同样的元素定位代码散落在各个脚本里一旦页面改了一个id你需要修改所有脚本。POM就是为了解决这个问题将页面元素定位和页面操作封装成单独的类。# 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.login_button (By.CSS_SELECTOR, .login-btn) def enter_username(self, username): self.driver.find_element(*self.username_input).send_keys(username) def enter_password(self, password): self.driver.find_element(*self.password_input).send_keys(password) def click_login(self): self.driver.find_element(*self.login_button).click() # 在你的测试脚本中 from login_page import LoginPage driver WebFirefox() login_page LoginPage(driver) driver.get(登录页URL) login_page.enter_username(test_user) login_page.enter_password(test_pass) login_page.click_login()这样做的好处是如果登录页面的id变了你只需要修改LoginPage这个类里的一个地方所有用到这个页面的测试脚本都自动生效。这是迈向编写可维护、大型自动化测试套件的重要一步。7. 常见问题排查与调试技巧实录即使按照教程一步步来你也可能会遇到问题。下面是我整理的“故障排除清单”覆盖了90%的常见错误。问题现象可能原因解决方案WebDriverException: Message: ‘geckodriver’ executable needs to be in PATH.系统找不到GeckoDriver驱动。1. 确认geckodriver文件已下载。2. 确认其所在目录已添加到系统环境变量PATH中或将其放在Python安装目录下。3. 重启命令行终端。SessionNotCreatedException: Unable to find a matching set of capabilities浏览器版本与驱动版本不匹配。检查Firefox浏览器版本下载对应大版本号的GeckoDriver。去GeckoDriver官网查看版本支持表。NoSuchElementException: Unable to locate element元素定位失败。1.检查定位器用F12开发者工具确认元素的id/class/selector是否正确注意是否在iframe内。2.检查时机元素是否还没加载出来在find_element前加入time.sleep或显式等待。3.检查唯一性定位器是否匹配了多个元素find_element只取第一个。ElementNotInteractableException: Element is not clickable at point元素不可交互。1. 元素被遮挡如弹窗。关闭遮挡物。2. 元素在视窗外。使用driver.execute_script(“arguments[0].scrollIntoView();”, element)滚动到元素位置。3. 元素状态为disabled。检查业务逻辑。Airtest的touch()命令报错TargetNotFoundError未在屏幕上找到匹配的图片。1.截图问题截图是否准确背景是否太杂乱运行脚本时浏览器窗口位置、大小、页面缩放比例是否与截图时完全一致2.阈值问题Template可以设置threshold匹配阈值默认0.8。如果画面有微小变化尝试降低阈值如Template(r”img.png”, threshold0.7)。3. 使用exists()函数先判断图片是否存在再进行操作。脚本在IDE里运行正常在命令行运行失败环境变量或当前工作目录问题。1. 确保在命令行中当前目录是你的脚本所在目录尤其是涉及图片路径时。2. 检查命令行中Python和pip的版本是否与IDE中使用的一致。Firefox启动后马上闪退可能是浏览器驱动与浏览器版本严重不兼容或存在多个Firefox实例冲突。1. 彻底关闭所有Firefox进程在任务管理器中结束firefox.exe。2. 使用driver WebFirefox(firefox_binary’Firefox可执行文件路径’)显式指定浏览器位置。调试技巧多用screenshot在关键步骤前后特别是失败前使用driver.save_screenshot(“step1.png”)保存截图能帮你直观看到当时的页面状态。打印信息多用print()输出当前URL、元素属性等信息。手动复现遇到问题时尝试手动操作一遍观察页面是否有异步加载、弹窗、重定向等意外行为。降低速度在开发调试阶段可以在操作之间加入time.sleep(1)让你能看清自动化过程便于定位问题。走到这里你已经从一个对自动化测试一无所知的新手变成了一个能够搭建环境、编写混合模式脚本、并具备基本排查能力的实践者。这套Airtest-Selenium的组合为你打开了一扇门。接下来你可以尝试用它们去自动化你日常工作中那些重复的网页操作比如数据抓取、报表生成、定期巡检等。记住所有复杂的自动化项目都是由一个个像“打开百度并搜索”这样的小脚本组合而成的。