news 2026/10/17 19:29:43

Python+Selenium+Webdriver环境搭建:从零跑通第一个Web自动化测试用例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python+Selenium+Webdriver环境搭建:从零跑通第一个Web自动化测试用例

简介:这份PDF资料面向准备入门Web自动化测试的开发者与测试人员,系统梳理了从零搭建Python+Selenium+Webdriver测试环境的完整流程。内容涵盖Python 3.x脚本语言、PyCharm开发工具、Selenium 3.x测试框架,以及Firefox(geckodriver)与Chrome(chromedriver)两类浏览器驱动的配置方式,并给出Windows 10下的具体操作路径与验证方法。资源包共1个PDF文件,约93KB,篇幅紧凑,适合作为环境搭建阶段的速查手册。文中还附带一段可直接运行的测试脚本示例,演示打开网页、定位搜索框、提交关键字并断言结果的核心写法,帮助读者理解驱动调用与元素操作的基本逻辑。目前已有3568人学习,适合刚接触自动化测试、需要快速跑通第一个Selenium脚本的初学者对照实践。

1. 从一台干净电脑到跑通第一个用例:Web自动化测试环境到底在搭什么

很多人第一次接触 Web 自动化测试,卡住的地方往往不是写不出脚本,而是环境根本跑不起来。浏览器版本对不上、驱动找不到、脚本一执行就报SessionNotCreatedException,这些和代码逻辑毫无关系的报错,能把一个下午耗光。标题里说的 Python+Selenium+Webdriver,本质上是三件事拼在一起:Python 负责写测试逻辑,Selenium 是操作浏览器的库,Webdriver 是浏览器厂商提供的、真正去驱动浏览器的那个可执行程序。三者版本必须咬合,缺一环就翻车。

这套环境适合谁?适合想把手动点击回归变成脚本回归的测试同学,也适合需要批量抓取页面状态、做 UI 冒烟检查的开发者。它不挑项目大小,一个登录流程、一个下单链路都能覆盖。下面我按一台干净机器从零开始,把每一步的命令、参数和判断标准讲清楚,你照着做就能跑通第一个用例,而不是停在装包这一步。

2. 装 Python 与虚拟环境:别让全局包污染你的测试工程

2.1 为什么一定要用虚拟环境

Web 自动化测试工程会依赖 selenium、pytest、可能还有 allure 报告库。如果全部装在系统全局 Python 里,过几个月另一个项目要不同版本的 selenium,两边就开始打架。虚拟环境的作用是给这个测试工程单独开一份包目录,删掉工程目录就等于卸载干净,不留残留。常见做法是在工程根目录下建一个venv,所有依赖只装进这里。

Python 版本选择上,我一般用 3.9 到 3.11 之间的稳定版。太老的版本部分新库不再支持,太新的版本偶尔会遇到某些依赖还没出对应 wheel 包。装完之后用python --version确认,别装完就往下走,版本没生效后面全是坑。

2.2 创建虚拟环境并安装核心依赖

# 进入你的测试工程目录 cd web_auto_demo # 创建虚拟环境,目录名就叫 venv python -m venv venv # 激活虚拟环境:Windows 用下面这行 venv\Scripts\activate # macOS / Linux 用这行 source venv/bin/activate # 激活后命令行前面会出现 (venv),再安装依赖 pip install selenium pytest # 确认装到了虚拟环境里,而不是全局 pip show selenium

这段命令的逻辑是:先建隔离目录,再激活让它成为当前 shell 的默认 Python,最后装包。pip show selenium会打印安装路径,如果路径里带venv,说明装对了;如果指向系统目录,说明激活没成功,后面所有依赖都会污染全局。参数上没什么可调的,venv是标准库自带模块,不需要额外安装。

提示:每次打开新终端都要重新激活虚拟环境,忘了激活就会出现「明明装了却 import 不到」的玄学问题。

2.3 用 requirements.txt 锁住版本

# 把当前环境的依赖和版本导出 pip freeze > requirements.txt # 换一台机器或重装时,一条命令还原 pip install -r requirements.txt

pip freeze会把当前所有包及精确版本写进文件,团队协作时别人拿到这个文件就能装出一模一样的环境。这一步是血泪经验:不锁版本,半年后重装,selenium 从 4.10 升到 4.20,某些 API 行为变了,脚本莫名其妙失败,你还以为是代码问题。

3. 浏览器与 Webdriver 的版本对齐:90% 的启动失败都在这

3.1 Webdriver 到底是什么

Selenium 本身不会操作浏览器,它只是发指令。真正执行点击、输入、跳转的是 Webdriver——一个由浏览器厂商提供的独立程序。Selenium 通过 HTTP 协议把命令发给 Webdriver,Webdriver 再去控制浏览器。所以浏览器、Webdriver、Selenium 库三者之间有一条版本链,任何一环错位都会导致会话创建失败。

早期做法是手动下载 chromedriver 放到 PATH 里,还要保证它和 Chrome 大版本号一致。现在主流做法是用 Selenium 自带的 Selenium Manager,它会自动检测本机浏览器版本并拉取匹配的驱动。但自动拉取依赖网络,公司内网或网络受限时经常失败,所以理解手动对齐仍然必要。

3.2 查看浏览器版本并匹配驱动

# 查看本机 Chrome 版本(Windows 在设置-关于 Chrome 里看,或命令行) # macOS 示例 /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version # 查看已安装的 chromedriver 版本 chromedriver --version

判断标准很简单:Chrome 主版本号(比如 126)必须和 chromedriver 主版本号一致。126 的浏览器配 125 的驱动,大概率报session not created: This version of ChromeDriver only supports Chrome version 125。小版本号可以不完全一致,主版本必须对齐。

3.3 用 Selenium Manager 自动管理驱动

from selenium import webdriver from selenium.webdriver.chrome.options import Options # 配置浏览器启动参数 options = Options() # 无头模式:不弹出浏览器窗口,适合 CI 环境 # options.add_argument("--headless=new") # 禁用部分沙箱特性,容器里跑时常加 options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") # Selenium 4.6+ 会自动调用 Selenium Manager 匹配驱动 driver = webdriver.Chrome(options=options) driver.get("https://example.com") print(driver.title) driver.quit()

这段代码里,webdriver.Chrome(options=options)在 Selenium 4.6 以上会自动触发驱动管理,不需要你手动指定驱动路径。--headless=new是新版无头模式,比老的无头模式更接近真实浏览器行为,很多在老无头下渲染异常的页面,用新模式就正常了。--no-sandbox和--disable-dev-shm-usage是容器环境的后悔药,不加经常在 Docker 里启动即崩。

注意:如果自动管理一直失败,就退回手动方案——下载对应版本驱动,在代码里用Service指定路径,别死磕自动。

4. 写出第一个可复现的测试用例:从打开页面到断言

4.1 用 pytest 组织测试

# test_login_demo.py import pytest from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options @pytest.fixture(scope="function") def driver(): """每个测试函数启动一次浏览器,结束后关闭""" options = Options() options.add_argument("--headless=new") options.add_argument("--window-size=1280,800") d = webdriver.Chrome(options=options) yield d d.quit() def test_page_title(driver): """打开页面并断言标题包含关键字""" driver.get("https://example.com") # 显式等待标题出现,避免页面没加载完就断言 from selenium.webdriver.support.ui import WebDriverWait WebDriverWait(driver, 10).until( lambda d: "Example" in d.title ) assert "Example" in driver.title

@pytest.fixture把浏览器的创建和销毁抽出来,每个用例独立一份,互不干扰。scope="function"表示每个测试函数都重新开浏览器,虽然慢一点但隔离性好;如果用例很多且互不影响,可以改成scope="module"复用。WebDriverWait是显式等待,10 秒内轮询直到条件成立,比time.sleep靠谱得多——固定睡眠要么不够要么浪费。

4.2 定位元素与常见定位策略

from selenium.webdriver.common.by import By # 按 id 定位,最快最稳 driver.find_element(By.ID, "username") # 按 name 定位 driver.find_element(By.NAME, "password") # 按 CSS 选择器,灵活 driver.find_element(By.CSS_SELECTOR, "button.submit-btn") # 按 XPath,功能最强但最脆 driver.find_element(By.XPATH, "//button[text()='登录']")

定位策略的优先级我一般这样排:id > name > CSS > XPath。id 唯一且稳定,XPath 写起来爽但页面结构一变就断,尤其是那种自动生成的层级路径。CSS 选择器在可读性和稳定性之间平衡最好。参数上,find_element找不到会抛NoSuchElementException,find_elements返回列表不抛异常,判断元素是否存在时用后者更安全。

4.3 运行与查看结果

# 运行当前目录下所有 test_ 开头的文件 pytest -v # 只跑某个文件 pytest test_login_demo.py -v # 失败时输出更详细的信息 pytest -v --tb=long

-v显示每个用例的名字和结果,--tb=long在失败时打印完整堆栈。第一次跑建议加上这两个参数,能看清到底是环境问题还是断言问题。如果报的是WebDriverException而不是AssertionError,那基本是环境没搭好,回到第 3 章检查版本对齐。

5. 避坑与排查:那些让环境搭不起来的高频问题

5.1 报 SessionNotCreatedException

现象:脚本一执行就抛SessionNotCreatedException,提示版本不匹配。原因:浏览器和 Webdriver 主版本号不一致,或者自动管理拉到了错误版本。解决:手动确认浏览器版本,下载对应主版本的驱动,用Service显式指定路径,绕开自动管理。

5.2 元素明明存在却定位不到

现象:页面上肉眼能看到按钮,find_element就是找不到。原因:元素在 iframe 里,或者页面还没渲染完。解决:先driver.switch_to.frame(...)切进 iframe 再定位;或者用WebDriverWait等元素可见,别用固定睡眠。

5.3 无头模式下行为不一致

现象:有界面时能跑通,加了--headless就失败。原因:老的无头模式渲染引擎和真实浏览器有差异,部分 JS 行为不同。解决:改用--headless=new,它复用真实浏览器的渲染路径,兼容性好很多。

5.4 容器里启动即崩

现象:本地跑得好好的,放进容器就报错退出。原因:容器共享内存太小,Chrome 启动时崩溃。解决:加--disable-dev-shm-usage,或者给容器加大/dev/shm空间。

5.5 中文路径或空格路径导致驱动找不到

现象:驱动明明在目录里,就是提示找不到。原因:路径含中文或空格,某些版本解析异常。解决:把工程和驱动放在纯英文无空格路径下,这是最省事的做法。

6. 让环境真正可用:并行、截图与持续集成的接入技巧

环境跑通一个用例只是起点,真正投入使用时你会关心三件事:跑得快不快、失败能不能留证据、能不能自动跑。先说并行。pytest 配pytest-xdist可以多进程跑用例,命令是pytest -n 4,4 是进程数。但要注意每个进程会各开一个浏览器,机器内存要够,否则并行反而更慢。我一般按 CPU 核数的一半来设,稳定优先。

再说失败留证。UI 测试最怕失败时只有一行报错,看不到当时页面长什么样。在 fixture 里加一段钩子,用例失败时自动截图:

@pytest.fixture(scope="function") def driver(request): options = Options() options.add_argument("--headless=new") d = webdriver.Chrome(options=options) yield d # 用例失败时截图,文件名带用例名 if request.node.rep_call.failed: d.save_screenshot(f"fail_{request.node.name}.png") d.quit()

这段逻辑依赖 pytest 的钩子拿到用例执行结果,request.node.name是用例名,截图按用例名存,排查时一眼能找到对应页面。参数上save_screenshot存的是当前视口,如果要整页截图得用 CDP 命令,普通排查视口够用。

最后是持续集成。把pytest -v写进流水线脚本,配合无头模式和--no-sandbox,就能在无人值守环境跑回归。这里有个我踩过的坑:CI 机器上浏览器版本会随镜像更新,某天镜像升级了 Chrome 但驱动没跟上,整条流水线红一片。后来我固定了浏览器镜像版本,并且把驱动版本也写进依赖清单,才稳定下来。环境这东西,能锁死的就别让它浮动。

我自己的习惯是,每搭好一套新环境,先写一个只做「打开页面、断言标题」的最小用例跑通,再往上叠业务逻辑。这个最小用例就是你的基线,后面任何报错,先跑它,能过说明环境没问题,问题在业务代码;不能过说明环境又变了。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 19:29:40

基于GitHub Actions自动化聚合500个AI模型动态的网站搭建实践

1. 从一条推送说起:为什么要盯住500个AI模型我平时有个习惯,早上泡咖啡的时候会顺手刷一遍模型发布列表。这个习惯大概从两年前开始,那时候能叫得上名字的模型也就几十个,手动翻一翻还能跟得上。到了今年,情况完全变了…

作者头像 李华
网站建设 2026/10/17 19:27:01

结构化表达:用可执行图表驱动跨角色对齐与工程落地

1. 项目概述:这不是画图,是用结构化思维解决真实问题的底层能力“diagram-design”这个标题乍看像一个工具操作指南,但在我带过的几十个跨领域项目里,它从来不是关于“怎么把流程图画得好看”,而是关于如何把模糊的业务…

作者头像 李华
网站建设 2026/10/17 19:25:54

树莓派入门避坑指南:系统烧录、GPIO与网络配置全覆盖

简介:《树莓派用户指南:从入门到实践》是一本由树莓派基金会创始人埃本厄普顿和加雷斯哈弗克里合著的电子书,以PDF格式提供,面向零基础用户和已有一定经验的开发者,覆盖从树莓派开箱设置、系统初始化到高级配置的完整学…

作者头像 李华
网站建设 2026/10/17 19:25:39

HTML5 Notification API 桌面通知实战:权限、参数与去重全解析

1. 桌面通知到底是个什么东西第一次在浏览器里看到右下角弹出系统级的通知卡片,我以为是装了什么插件。后来翻代码才发现,这玩意儿是浏览器原生能力,一行new Notification(标题)就能调起来。它不依赖任何第三方库,不需要引入外部脚…

作者头像 李华
网站建设 2026/10/17 19:25:03

视觉目标跟踪丢失后如何重定位:从判定到工程落地

1. 从“跟丢”说起:为什么重定位是视觉跟踪的必修课做过视觉目标跟踪的人都有一个共识:跟踪算法在理想场景下跑得再漂亮,都不如它在目标丢失后能不能自己找回来更能说明问题。我最早接触跟踪任务时,天真地以为只要把检测器做好、把…

作者头像 李华
网站建设 2026/10/17 19:22:16

新型储能白皮书怎么读?从装机口径到项目测算的实操指南

简介:《中国新型储能行业发展白皮书》由储能领跑者联盟发布,是一份面向能源行业分析师、企业决策者、政策研究者及投资者的行业研究报告,旨在厘清碳中和背景下新型储能的市场机遇与技术挑战。内容涵盖全球源网侧、工商业、户用储能市场概况&a…

作者头像 李华