资讯详情

资讯详情

Python+Selenium自动化测试环境搭建与实战案例

1. 这个项目到底在解决什么问题先聊点实在的Selenium是目前自动化测试领域绕不开的一个工具不管是做Web UI自动化、回归测试还是用浏览器模拟真实用户操作你迟早要和它打交道。这个入门项目本质上就两件事——把Selenium测试环境从零搭起来再跑通一个真实可用的脚本走一遍打开浏览器→定位元素→模拟输入→点击操作→结果断言的完整链路。我为什么专门写环境搭建这部分因为我见过太多新手第一次接触自动化测试不是死在代码逻辑上而是死在环境上。报错信息五花八门有的是Chrome版本和Driver版本差一位导致启动失败有的是PATH路径没配好命令找不到有的是浏览器驱动压根没下载。这些坑你光看官方文档是看不出来的——文档只会告诉你应该这样装但绝不会告诉你新手下场十有八九会这样踩坑。这个项目最适合三类人想转测试开发或自动化测试岗的工程师、负责回归测试想提升效率的QA、以及写爬虫时想用Selenium处理复杂交互的Python用户。前提是你对Python基础语法有最底层的了解比如能看懂import、def、if这类关键字。如果是纯零基础建议先花一周过一遍Python入门教程再回来读这篇否则代码部分容易跟不上。需要提前说明的是Selenium 4.x版本相比3.x变化非常大比如find_element_by_id这种旧API在4.x里已经废弃了统一改成了find_element(By.ID, xxx)的写法。这篇文章里所有示例均基于Selenium 4.x如果你之前看的是3.x的老教程有些代码直接抄过来是会报错的。2. 环境搭建的完整流程与关键决策2.1 为什么选择Python Selenium这个组合做Web自动化测试主流选型无非就是Python、Java、JavaScript三条路线。我最终选择Python不是因为它性能最好——恰恰相反Selenium本身是C/S架构真正干活的其实是WebDriver语言层只是负责发指令性能瓶颈根本不在语言上。选Python的核心原因是生态和开发效率。pytest、allure这些配套测试工具非常成熟代码量比Java版本少一半不止调试起来直观而且对没有Java深厚背景的测试人员来说学习曲线最平滑。你可以类比成开车Java路线像是手动挡越野车性能上限高但操作复杂Python路线像是自动挡轿车日常通勤效率极高绝大多数场景都够用。2.2 三层安装法每一步都要验证在这里我把环境搭建分成三个层次每一层装完都要确认成功再进入下一层千万别一口气全装完再统一排查那样出问题很难定位是哪个环节挂了。**第一层Python基础环境。**建议直接安装Python 3.10以上版本安装时务必勾选Add Python to PATH选项。这一步很多人漏掉后果是在命令行敲python提示找不到命令。如果已经安装但没勾选可以手动把Python安装目录和Scripts目录加到系统环境变量里不会操作就卸载重装一次省得后期总出幺蛾子。装完在终端验证python --version能输出Python版本号就说明基础环境没问题。**第二层Selenium库。**用pip安装国内网络建议加清华镜像源速度差别非常大pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple装完用pip show selenium查看版本信息。这里有一个非常隐蔽的坑如果你的电脑上同时装了多个Python环境比如Anaconda和系统Python共存pip命令可能指向的是另一个解释器会导致库装进去了但代码运行时依然报ModuleNotFoundError。稳妥的做法是用python -m pip install selenium确保pip和python属于同一个环境这条经验够你避免浪费半小时。**第三层浏览器驱动。**这是新手翻车率最高的一步。Selenium本身不具备操纵浏览器的能力它通过WebDriver这个中间层和浏览器通信。你可以把WebDriver理解成给浏览器安装的一个遥控器Selenium发送指令WebDriver负责执行。Chrome对应chromedriverFirefox对应geckodriverEdge对应msedgedriver三者不能混用。Chrome用户请注意从Selenium 4.6版本开始内置了Selenium Manager会自动检测本机Chrome版本并下载匹配的Driver理论上你什么都不用管。但这个自动功能依赖网络访问官方驱动的仓库如果下载失败了仍然需要手动处理。手动操作时的铁律是驱动主版本号必须和Chrome主版本号一致。查看Chrome版本的办法是地址栏输入chrome://version。比如你的Chrome是120.x就下载120开头的chromedriver如果下载的是119的驱动启动时必然报SessionNotCreatedException。这个版本对应关系我踩过太多次了差一位都不行。下载完成后在Windows下直接把chromedriver.exe放到Python安装目录的Scripts文件夹里因为Scripts目录已经在PATH里代码会自动找到它省去配置路径的麻烦。macOS或Linux用户则建议把驱动放到/usr/local/bin。2.3 用最小化脚本验证环境全链路环境装完先别急着写正式脚本用一段最小化代码把链路跑通from selenium import webdriver driver webdriver.Chrome() driver.get(https://www.baidu.com) print(driver.title) driver.quit()如果这段代码能弹出一个Chrome窗口正常打开百度并打印出百度一下说明从Selenium库到WebDriver到浏览器整条链路全部通了。如果在这里就报错按顺序排查三件事浏览器是否正常启动、驱动版本是否和浏览器匹配、驱动路径是否被找到。我见过有人卡在这段代码上求助最后发现是Chrome浏览器本身出了问题把浏览器卸载重装后立刻好了——所以这类问题别总认为是代码的锅环境因素要先排除。3. 第一个实战案例自动搜索与结果断言3.1 案例场景为什么这样选这个案例我设计的是打开百度→输入搜索关键词→回车→等待结果加载→抓取标题→断言非空→截图”它几乎覆盖了Selenium最核心的五大操作元素定位、输入框交互、键盘操作、显式等待、断言验证。这五个技能点学会日常80%的Web自动化测试场景你都能应付。为什么不直接拿一个登录案例因为登录需要现成的测试账号而大多数读者手里只有真实账号拿真实账号反复跑自动化测试容易触发目标系统的安全风控万一被锁定就很麻烦。百度搜索这个场景公开、稳定、无副作用作为入门案例再合适不过。练习登录流程时更好的办法是在本地起一个测试专用页面或者使用开源项目自带的demo网站别拿生产环境练手。3.2 完整脚本与运行效果以下是完整代码为了方便阅读每一步都加了注释import time 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 # 初始化浏览器对象 driver webdriver.Chrome() driver.maximize_window() try: # 1. 打开目标页面 driver.get(https://www.baidu.com) # 2. 定位搜索输入框输入关键词 search_input WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, kw)) ) search_input.send_keys(Selenium 自动化测试) search_input.send_keys(Keys.ENTER) # 3. 等待搜索结果加载完成 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, div.result)) ) # 4. 抓取搜索结果标题 results driver.find_elements(By.CSS_SELECTOR, h3) top_results [r.text for r in results[:5]] # 5. 断言搜索结果不为空 assert len(top_results) 0, 搜索结果为空断言失败 print(断言通过共获取 {} 条结果.format(len(top_results))) print(前5条标题) for i, title in enumerate(top_results, start1): print({}. {}.format(i, title)) # 6. 截图留档 driver.save_screenshot(search_result.png) print(截图已保存) finally: # 7. 关闭浏览器 driver.quit()运行后如果你看到终端输出了5条搜索标题同时项目目录下生成了一张search_result.png截图恭喜你你的第一个自动化测试脚本已经正式跑通了。3.3 代码背后的关键设计逻辑这段代码看似简单但里面有几个设计点非常值得展开说直接决定了你后续写测试代码的思维。先说等待策略。新手最常见的写法是time.sleep(2)定死两秒但这是典型的反面教材。页面加载时间受网络、服务器性能影响波动极大sleep两秒可能页面还在转圈下一秒元素才出来然后代码就报NoSuchElementException反过来如果网速快一秒钟就加载完你又白白多等了一秒。显式等待WebDriverWait则完全不同它的机制是轮询检测某个条件是否成立比如presence_of_element_located表示元素只要出现在DOM里就继续往下走页面1秒加载好就1秒继续5秒才加载好就最多等5秒完全自适应。记住这个理念用条件等待代替固定等待永远不要用sleep去赌网络速度。这也是面试官最爱问的一个考察点。再说定位方式的选择。代码里我用By.ID定位搜索框因为百度的搜索框同时有idkw和namewd两个稳定属性ID在页面中的唯一性最好。实际项目中元素定位的优先级顺序一般是ID name CSS选择器 XPath。XPath虽然被称为万金油但坏处是路径表达式往往很长而且只要页面结构稍微调整选择器就崩了。能用语义化属性解决的尽量别用一长串//*[id...]/div[2]/span[3]这种路径。再说断言的意义。这一步可以说是自动化测试和普通爬虫脚本最本质的区别。爬虫的目标是拿到数据跑完就算成功测试的目标是验证行为必须有预期结果和实际结果的比对否则脚本跑完你根本不知道它是成功还是成功了一大半、错了一小半。这个案例里断言的是搜索结果不为空真实项目里的断言对象五花八门登录后的用户名文本、跳转后的URL、某个关键按钮的可见状态、接口返回的状态码等等。断言写得越贴近业务核心测试的价值就越大。最后说异常处理结构。try...finally的写法确保无论中间哪一步报错driver.quit()都会被执行浏览器进程不会残留在系统里。很多新手脚本没有这一步跑一次卡死一次任务管理器里堆了一堆chrome.exe进程低配电脑直接被拖垮。尽早养成这个习惯后面受益无穷。3.4 定位不到元素时怎么办定位不到元素是自动化测试里出现频率最高的问题没有之一。我自己调试时的排查顺序分享出来第一在报错位置前加一行print(driver.page_source)看页面当前的真实DOM结构。很多时候你以为页面长这样但因为异步加载、弹窗遮挡、iframe嵌套等原因实际DOM里根本没有你写的那个选择器。第二检查元素是否在iframe里。iframe本质上是一个嵌套的独立页面主页面DOM里根本找不到它的内部元素。必须先driver.switch_to.frame(frame_id)切进去才能操作操作完再driver.switch_to.default_content()切回主页面。这个切换动作极其容易遗漏而且切进去之后忘了切回来后面定位主页面元素就一路报错非常折磨人。第三考虑元素是否为动态渲染。现在主流前端框架Vue、React等大量使用异步数据加载元素可能是在Selenium执行到定位语句时才被JS插入到DOM里的。这时唯一的解法就是前面说的显式等待等元素真正出现在DOM里再继续。4. 用pytest把脚本升级成正规测试工程4.1 为什么说裸脚本不够正式上面那段脚本能跑但距离工程化还差一大截。真实测试项目里没有人会用if __name__ __main__去逐个裸跑脚本大家都是用测试框架来组织和管理用例。Python生态里最主流的选择就是pytest。它带来的几个直接收益我列一下断言表现力强pytest原生支持assert语句断言失败时自动输出预期的值和实际的值一眼就能看出哪里不匹配不需要自己写print调试。fixture机制管理资源浏览器这种用前启动、用完关闭的样板代码可以封装成fixture多个用例自动复用或清理代码重复度大幅下降。自动收集用例只要函数名以test_开头pytest就能自动发现并执行支持按文件名、关键字、标记mark灵活筛选。生态配件齐全配合allure-pytest可以生成带图表、日志、截图的可视化测试报告团队评审和向上汇报时能拿出体面的交付物。4.2 改造后的完整代码把刚才的搜索案例改造成pytest风格过程并不复杂。先安装pytest依赖pip install pytest -i https://pypi.tuna.tsinghua.edu.cn/simple然后新建一个test_baidu.py文件内容如下import pytest 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 pytest.fixture(scopemodule) def driver(): 管理浏览器生命周期的fixture d webdriver.Chrome() d.maximize_window() yield d d.quit() def test_baidu_search(driver): 测试百度搜索功能 driver.get(https://www.baidu.com) search_input WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, kw)) ) search_input.send_keys(pytest 自动化测试) search_input.send_keys(Keys.ENTER) WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, div.result)) ) results driver.find_elements(By.CSS_SELECTOR, h3) titles [r.text for r in results] assert len(titles) 0, 搜索结果为空 assert all(titles), 存在空的标题元素命令行执行pytest test_baidu.py -v --tbshort-v用来输出每个用例的详细执行状态--tbshort控制报错堆栈的简洁程度调试阶段这两参数几乎是标配。4.3 fixture作用域的选择逻辑上面fixture用了scopemodule意思是同一个测试模块内的所有用例共用同一个浏览器实例。这样设计是基于执行效率的考虑如果每个用例都重新打开浏览器执行时间成倍增长尤其是用例数量上了几十条之后差距非常明显。但共用实例也有代价——用例之间会互相污染。比如第一个用例登录了某个账号第二个用例如果不处理登录状态它的断言可能莫名其妙就通过了而你不知道这个通过是业务逻辑正确还是沾了前一个用例的光。这种用例间的不独立性是自动化测试里著名的测试泥潭问题。初学者先理解概念即可等用例规模大了再按业务模块拆分不同的fixture作用域甚至结合工厂模式做动态参数化。4.4 测试报告怎么生成pytest跑完默认只在终端输出文字结果如果团队需要可视化报告最流行的方案是Allure。安装和生成报告的流程是pip install allure-pytest pytest test_baidu.py --alluredir./reports allure serve ./reportsallure serve会启动一个本地服务并自动打开浏览器展示报告里面能看到每条用例的通过/失败状态、耗时、失败时的log和截图附件。如果需要在CI流水线里留存报告还可以用allure generate生成静态HTML页面。这一步虽然不涉及业务逻辑本身但当你需要向非技术同事证明自动化测试确实有在干活的时候一份带图带数据的报告比说一百句话都管用。5. 常见问题排查速查表与避坑心得5.1 高频报错对照速查表以下是我在这些年实操中整理出来的高频报错对照表覆盖了入门阶段可能遇到的绝大部分问题报错信息可能原因解决办法SessionNotCreatedException: This version of ChromeDriver only supports Chrome version XXchromedriver与Chrome版本不匹配在chrome://version查看浏览器版本下载对应主版本号驱动WebDriverException: unknown error: cannot find Chrome binarySelenium找不到Chrome安装路径通过Options.binary_location参数指定Chrome可执行文件路径NoSuchElementException元素定位失败页面未加载完或选择器写错先加显式等待再用page_source确认元素是否真实存在TimeoutException等待条件一直未满足确认URL是否正确、选择器是否唯一、是否需要处理iframeElementNotInteractableException元素存在但不可操作被遮挡或隐藏检查元素是否在iframe中、是否被弹窗遮挡、是否需要先滚动到可见区域ModuleNotFoundError: No module named selenium库装到了别的Python环境改用python -m pip install selenium确保pip与python同环境5.2 几个容易忽略的细节坑第一个坑是浏览器驱动残留。脚本一旦异常中断chromedriver对应的Chrome进程会驻留在后台。Windows上症状明显任务管理器里出现大量chrome.exe电脑越来越卡。代码里用finally确保driver.quit()是治本之策但如果遇到顽固残留还是得手动结束进程。我一般会在写较长的用例时在启动浏览器前先清理一次历史残留进程这个习惯帮我省了很多麻烦。第二个坑是浏览器自动化特征被检测。越来越多的网站开始检测自动化操作特征最典型的就是navigator.webdriver属性。Selenium可以通过ChromeOptions加一些启动参数来隐藏自动化痕迹from selenium.webdriver.chrome.options import Options options Options() options.add_argument(--disable-blink-featuresAutomationControlled) options.add_experimental_option(excludeSwitches, [enable-automation]) driver webdriver.Chrome(optionsoptions)需要强调的是这种方法不能保证100%生效反爬和反检测都在持续升级而且学习阶段不建议一上来就用这套配置。先用正常模式跑通核心逻辑等真正需要在受限网站做测试时再研究对抗手段这个顺序不能反。第三个坑是测试数据污染。反复跑同一份搜索、注册、下单脚本会在目标系统里残留大量垃圾数据。正规的自动化测试必须考虑数据隔离要么在独立的测试环境跑要么每次执行后主动清理数据。我见过有人把开发环境的数据库跑满测试垃圾数据的这种事故非常影响团队信任。入门阶段至少要知道这个概念自动化测试不只是写代码还要考虑它产生的副作用。5.3 调试时的几个实用技巧调试Selenium脚本时有几个很实用但大家都不会写在文档里的技巧一个是临时降低速度。调试阶段可以在关键操作之间加time.sleep(0.5)让每一步的执行节奏慢下来肉眼跟得上确认每一步状态正确后再删掉。另一个是善用driver.get_screenshot_as_png()或save_screenshot在关键节点截图定位问题时不用靠猜。还有一个是打印当前页面状态——driver.current_url看URL是否跳转到位driver.title看页面标题是否符合预期这两个属性在排查问题时信息量非常大。6. 从入门到能上手的进阶路线建议6.1 先吃透这几个核心API入门阶段最需要掌握的核心API其实屈指可数不要被官方文档的庞大体量吓住。按优先级排序find_element系列用于定位元素、send_keys用于模拟输入、click用于点击操作、WebDriverWait配合expected_conditions用于等待、switch_to用于切换iframe或窗口。这五个能力覆盖了大多数日常用例的编写。至于ActionChains拖拽右键、execute_script执行JavaScript、文件上传下载、cookie操作等等属于按需查阅的范畴遇到具体场景再针对性去查文档即可。先建立能跑通的信心比先背完所有API重要得多。6.2 从能跑迈向可靠的四项改造写完第一个自动化脚本后下一步不是急着学更多新API而是补上工程化的关键环节第一用pytest管理用例这篇前面已经示范了怎么改造。第二把测试数据抽离出来——URL、测试账号、搜索关键词等不要硬编码在代码里放到配置文件或环境变量中换环境跑的时候只改配置不动代码。第三在关键步骤自动截图用例失败时能直接复盘现场。第四学习Page Object Model模式把页面的元素定位和操作方法封装成独立的类测试用例只关心业务步骤。这个设计模式的核心价值在于当页面改版时只需要改对应的Page类测试用例不用跟着改维护成本直线下降。6.3 后续扩展的几个方向参考沿着自动化测试这条路往下走大致有这些方向可供挑选数据驱动测试把测试数据放在Excel、YAML或JSON里一套代码自动跑多组数据覆盖更多边界场景。无头浏览器模式用options.add_argument(--headless)让浏览器在后台运行不弹界面适合在CI/CD流水线里作为回归测试的一环。Selenium Grid分布式执行在多台机器上并行跑用例显著缩短完整回归测试的时间。接口自动化补充用requests加pytest做接口层的测试和UI自动化形成互补。UI自动化验证用户交互流程接口自动化验证数据正确性两者结合才是完整的质量保障体系。这几个方向每一个都值得单独写一篇长文展开。我个人观点是别贪多先把今天这个案例吃透——环境搭建过程中遇到的每个报错都记录下来搜索案例背后的等待机制和断言思维真正理解然后再一步步走向pytest、POM、数据驱动。自动化测试这个岗位经验沉淀比知道多少API重要得多。同样是应聘测试开发能讲清楚为什么用显式等待而不用sleep的人和只会贴代码的人面试官一把就能分辨出来。我在实际带人时还有一个明显的体会能把环境搭建一次讲清楚的人后面的学习速度普遍快很多。因为环境问题本质上是系统思维的问题——版本、路径、依赖、运行原理一环扣一环思路理顺了后面学什么都快反之环境一知半解后面几乎每跑一步都会卡壳最后多半会消磨掉热情。今天这个项目虽然只是自动化测试的入门口但它恰恰是整条路上最值得打牢的地基。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →