新闻详情

新闻详情

首页 / 资讯中心 / 详情

Selenium Web自动化测试实战:从环境搭建到框架落地

发布时间:2026/10/1 16:54:33来源:尧图网络
Selenium Web自动化测试实战:从环境搭建到框架落地
很长一段时间里我面试测试开发岗位时总会抛出一个问题“你写自动化脚本第一个用例是跑通就收工还是会继续想页面元素为什么这样定位、等待为什么这样写”十个人里有八个倒在第二问上。这其实也是很多初学者卡壳的原因Selenium的API就那么几个find_element、click、send_keys背三天就能唬人但真正扔给你一个动态渲染的前端项目脚本跑不过十分钟就碎一地。所以这篇不打算只贴一堆“Selenium入门语法”而是从一次完整的Web自动化测试实战出发把从环境搭建、脚本设计、框架集成到问题排查的完整链路拆开讲重点讲清楚每一步背后的取舍逻辑。目标读者是已经会一点Python、想系统掌握自动化测试但还没完整落地过项目的朋友这篇的内容够你直接参考复现也能帮你避开我踩过的那堆坑。1. 自动化测试的方案设计与技术栈选型1.1 为什么选Selenium而不是其他工具聊Web自动化绕不开工具选型。市面上能用的东西其实不少Playwright、Cypress、Appium移动端、Robot Framework这类关键字驱动框架还有各路国产平台。但我个人做PC端Web功能回归、UI稳定性验证尤其是需要兼容老系统的场景最顺手的仍然是Selenium。原因有三第一Selenium的兼容性覆盖面是最广的。WebDriver是W3C标准各主流浏览器都原生支持这意味着同一个脚本可以无缝跑在Chrome、Firefox、Edge上不用针对浏览器单独改逻辑。Playwright虽然也支持多浏览器但它的浏览器补丁管理在某些内网环境——尤其是不允许随便下载二进制文件的企业环境——会非常难受Selenium直接调本地浏览器就能规避这个问题。第二生态太成熟了。Selenium从2010年左右火起来到现在十多年社区沉淀了大量踩坑文档、驱动管理工具、框架集成案例。遇到问题一搜基本都有答案。这种“前人填坑”的积累程度直接决定了你上手的顺畅度。Playwright确实更现代但相对年轻我在生产环境遇到的一些边缘问题社区答案确实不如Selenium丰富。第三团队协作成本。Selenium配合pytest或TestNG、再配一个Allure报告团队里任何人都能快速理解脚本结构。而很多封装过度的平台框架写脚本的人爽了接手的人能骂街。Selenium的可读性和直白程度天然适合团队协作。当然如果项目是纯新项目、团队没有历史包袱我也会认真考虑Playwright——它的自动等待机制和拦截网络请求的能力确实做得比Selenium好。但如果你是想系统打基础Selenium一定是第一站因为它把“浏览器自动化”的底层逻辑暴露得最清楚驱动、浏览器、元素、等待一整套概念搞明白之后用Playwright、Appium都是降维打击。1.2 核心工具链Python、Selenium、pytest的角色分工这次实战用到的主要组件就四个Python、Selenium WebDriver、pytest、还有一根WebDriver Manager。各司其职Python胶水语言负责整个测试脚本的逻辑编排。选择Python而不是Java主要是因为语法简洁、库丰富写UI测试用例时不需要啰嗦的样板代码。会一点Java的用TestNG效果也不差但对大多数团队来说Python的招募成本和上手曲线都更友好。Selenium WebDriver负责和浏览器对话。它本质上是暴露了一组HTTP接口的服务Python脚本通过这些接口向浏览器发指令——“打开这个URL”“找到这个元素”“点击它”“输入这段文字”。pytest测试执行框架。Selenium解决的是“如何操作浏览器”但“哪些用例要跑”“跑完结果怎么收集”“失败要不要重试”这些测试管理问题得靠pytest来管。pytest的fixture机制还能优雅地处理setup/teardown——每个用例执行前打开浏览器、执行完关闭这是原生Selenium脚本很难优雅解决的。WebDriver Manager自动下载并匹配浏览器版本的驱动文件。没有它你得手动去找ChromeDriver、GeckoDriver还得操心浏览器升级后驱动失效的问题。这几者组合起来的流程大致是pytest把测试用例收集起来通过fixture初始化WebDriver实例WebDriver去操控真实浏览器执行你在用例里写的操作步骤操作过程中捕获页面状态用作断言最终pytest汇总测试结果生成报告。1.3 项目结构和测试场景准备开始写代码之前建议先想清楚测试对象。这篇实战我用的演示场景是一个典型的后台管理系统——包含登录页、数据列表页和表单提交页这是Web项目最高频的三种页面形态。登录页涉及输入框操作和按钮点击列表页涉及等待异步数据加载和表格元素定位表单页涉及select下拉、日期控件、文件上传这类特殊交互覆盖了日常自动化测试的大部分典型痛点。项目目录我建议按这样的结构组织web_auto_test/ ├── conftest.py # pytest fixture 全局配置管理浏览器实例 ├── pages/ # 页面对象层每个页面一个类 │ ├── __init__.py │ ├── login_page.py │ ├── list_page.py │ └── form_page.py ├── testcases/ # 测试用例层只写断言和用例编排 │ ├── __init__.py │ ├── test_login.py │ ├── test_list.py │ └── test_form.py ├── data/ # 测试数据文件可用yaml/json/excel │ ├── test_data.json │ └── login_users.yaml ├── reports/ # 测试报告输出目录 └── requirements.txt这种分层结构叫作Page Object ModelPOM是Selenium自动化测试领域最主流的架构模式。核心思想就一句话把“页面元素定位”和“业务操作”封装到独立的Page类里测试用例只负责描述业务场景和断言结果不直接碰“怎么找元素”的细节。好处是当前端改了元素id或class时只需要改Page类里对应的那一个定义所有断言这个页面的用例自动修复不用满工程去搜索替换维护成本大幅下降。2. Selenium核心机制深度拆解2.1 WebDriver的工作原理与浏览器驱动管理很多新手把WebDriver当成一种“Python库”其实它是独立的服务进程。完整的工作链路是这样的你的Python脚本调用Selenium的APISelenium的客户端库把这次调用封装成一个HTTP请求发送给WebDriver可执行文件启动的服务WebDriver再去调用浏览器原生的自动化接口驱动浏览器执行真实操作。这里有个关键点WebDriver的版本必须和浏览器版本严格匹配。Chrome 120对应ChromeDriver 120.xFirefox对应GeckoDriver版本对不上启动浏览器时会直接抛SessionNotCreatedException。手动管理驱动确实麻烦所以我后面全部改用webdriver-manager这个库它会根据你的浏览器版本自动下载对应驱动并缓存到本地from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager def create_browser(): service Service(ChromeDriverManager().install()) options webdriver.ChromeOptions() options.add_argument(--start-maximized) # 如需要无界面模式取消下面注释 # options.add_argument(--headless) driver webdriver.Chrome(serviceservice, optionsoptions) return driver首次运行时会看到webdriver-manager去下载驱动的日志之后会走本地缓存基本几秒钟就能启动。这套方案在企业内网环境下可能因为网络限制卡住但大多数情况下比自己手动维护驱动要省心太多。2.2 元素定位八种策略的选用原则Selenium提供八种元素定位方式id、name、class_name、tag_name、css_selector、xpath、link_text、partial_link_text。实际项目里用得最频繁的是id、css_selector和xpath这几种。我个人的选用原则按优先级排id优先。id在HTML规范里要求页面内唯一定位速度快、代码简洁后端管理系统里的关键元素大多会带上id。比如登录按钮写成button idloginBtn直接driver.find_element(By.ID, loginBtn)就够了。css_selector次之。现代前端框架Vue、React生成的页面里id不一定是稳定的但class往往是语义化的。css_selector写法紧凑、性能好支持复杂的层级关系。xpath兜底。xpath是万金油页面结构特别混乱、没有合适的class时用xpath的文本定位或轴定位通常能解出来。但xpath性能相对差语法也容易写出一长串屎山一样的表达式能用css尽量不用xpath。举个例子需要定位一个表格里的“操作”列下的“编辑”按钮css写法可能是# 找到包含文本编辑的按钮且它位于id为dataTable的表格区域内 driver.find_element(By.CSS_SELECTOR, #dataTable .btn-edit)如果页面结构不稳定用xpath的文本匹配更稳driver.find_element(By.XPATH, //button[contains(text(), 编辑)])这里说一个很多新手会踩的坑定位表达式不要写得太绝对。比如//*[idapp]/div/div[2]/div[1]/div[3]/button这种“绝对路径”前端稍微加一层div就全盘崩溃。更稳的做法是先找不变的外层容器再在容器内用相对关系定位。还有能用By.ID就少用By.XPATH别为了耍帅硬写长表达式。2.3 显式等待、隐式等待与强制休眠的正确姿势Selenium脚本最常见的不稳定因素就是页面元素还没加载出来就开始操作导致NoSuchElementException。不少人图省事直接sleep(3)先不管精确性这也能跑。但遇上网络波动3秒不够就翻车遇上秒开页面又白白等3秒测试总时长被拖得很长。WebDriver提供了两套正经的等待机制隐式等待implicitly_wait设置后全局所有find_element操作会在元素没找到时轮询等待一段时间再报错driver.implicitly_wait(10) # 最多等10秒显式等待则是针对特定元素的条件等待用WebDriverWait配合expected_conditionsfrom selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, dataTable)) )两者可以共存但要小心隐式等待和显式等待叠加时最坏等待时间会膨胀到两者的总和。所以我的习惯是全局只设一个较短的隐式等待比如5秒对关键异步元素用显式等待精确控制。关于等待条件的选择presence_of_element_located只表示元素存在于DOM树不代表可见可点击。所以点按钮之前更严谨的条件是element_to_be_clickable输入框需要可见时用visibility_of_element_located。这个区别在实际项目里直接决定了脚本命不命中最刁钻的bug。3. 从零实现自动化脚本的完整实操3.1 环境准备安装Python与配置虚拟环境如果你机器上还没装Python先去python.org下载对应系统的安装包。这一步有个细节Windows安装时记得在引导页面勾选“Add Python to PATH”不然装完了命令行里敲python没反应会让你怀疑人生。装完验证一下python --version然后为这个项目创建独立的虚拟环境避免依赖污染系统Pythonmkdir web_auto_test cd web_auto_test python -m venv venv # Windows激活虚拟环境 venv\Scripts\activate # macOS/Linux激活虚拟环境 source venv/bin/activate创建虚拟环境这个步骤我强烈建议不要省——你后面同时搞爬虫、数据分析、Web开发时就知道依赖隔离有多重要了。然后安装依赖pip install selenium pytest webdriver-manager把依赖版本固化下来pip freeze requirements.txt这样换机器或同事接手时pip install -r requirements.txt一步搞定。3.2 第一个冒烟脚本打开浏览器并验证页面标题环境准备好后先从最简单的冒烟用例开始验证Selenium能够成功驱动浏览器。新建一个临时文件smoke_test.pyfrom selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager driver webdriver.Chrome(serviceService(ChromeDriverManager().install())) try: driver.get(https://example.com) assert Example Domain in driver.title print(冒烟测试通过页面标题, driver.title) finally: driver.quit()跑一下看效果python smoke_test.py如果看到Chrome窗口自动打开、跳转页面、然后打印出标题并关闭恭喜你的自动化环境已经通了。这一步虽然简单但一次性打通了“驱动下载→浏览器启动→页面访问→断言→资源回收”的完整链路后续所有脚本都是在这个基础上长出来的。3.3 登录用例实战输入框、按钮与流程断言拿一个模拟的后台登录页来演示你可以在本地起一个简单的HTML服务或者用测试环境。先写Page类把登录页的元素和操作封装起来# pages/login_page.py from selenium.webdriver.common.by import By class LoginPage: def __init__(self, driver): self.driver driver # 元素定位集中管理前端改动只改这里 _username_input (By.ID, username) _password_input (By.ID, password) _login_button (By.ID, loginBtn) _error_tip (By.CLASS_NAME, error-message) def input_username(self, username): self.driver.find_element(*self._username_input).clear() self.driver.find_element(*self._username_input).send_keys(username) def input_password(self, password): self.driver.find_element(*self._password_input).clear() self.driver.find_element(*self._password_input).send_keys(password) def click_login(self): self.driver.find_element(*self._login_button).click() def login(self, username, password): self.input_username(username) self.input_password(password) self.click_login() def get_error_tip(self): return self.driver.find_element(*self._error_tip).text注意两个实操细节第一个是输入前先.clear()。如果上一次用例失败导致输入框里残留了值不清空直接send_keys会把新旧内容拼在一起而且这个bug很难排查。第二个是把元素定义成类属性的元组调用时用*解包。这是Selenium社区比较通行的写法——元素定位和操作分离维护时只看顶部那几行定位即可。然后写登录场景的测试用例# testcases/test_login.py from pages.login_page import LoginPage def test_login_success(init_driver): driver init_driver driver.get(http://your-test-site.com/login) login_page LoginPage(driver) login_page.login(admin, 123456) # 断言登录成功后跳转到首页且页面出现欢迎语 assert 欢迎 in driver.page_source这里init_driver是conftest.py里定义的一个fixture负责创建浏览器、用例结束后关闭浏览器。3.4 复杂交互下拉选择、iframe、弹出框与文件上传实际业务系统没这么乖巧总有几个页面爱用特殊控件。这里集中说一下四种高频特殊交互。下拉框。原生select元素可以用Selenium封装的Select类from selenium.webdriver.support.ui import Select select_element driver.find_element(By.ID, category) Select(select_element).select_by_visible_text(电子设备)但如果前端用了第三方组件库比如Element UI、Ant Design的定制下拉页面上实际渲染的不是原生select而是div模拟的列表这时候Select类就不管用了得改为点击下拉框容器→等待列表出现→点击目标选项文本。iframe。有些页面把富文本编辑器或第三方地图嵌在iframe里直接用外层driver找里面的元素是找不到的必须切进去driver.switch_to.frame(driver.find_element(By.ID, editorFrame)) # 操作iframe内部的元素 ... # 操作完记得切回主文档 driver.switch_to.default_content()网页弹窗。分成操作系统原生alert和页面自定义modal两种。原生alert用driver.switch_to.alert.accept()处理页面modal本质是普通div按普通元素定位即可但要注意等待动画结束再点击。文件上传。input标签的文件框可以直接send_keys传本地路径这是最坑也最简单的方式driver.find_element(By.ID, uploadFile).send_keys(/path/to/local/file.pdf)不需要去模拟点击系统的文件选择窗口那个反而是自动化的大坑。3.5 等待策略与防抖处理前端路由跳转后新页面的数据往往是异步接口加载的。如果接口返回慢脚本立即去找表格里的数据极大概率扑空。我常用的终极等待策略是“等待目标元素可见且元素文本符合预期”WebDriverWait(driver, 10).until( lambda d: d.find_element(By.ID, dataTable).text ! )这个lambda写法轮询检查表格内容非空比EC.presence_of_element_located更贴近业务场景——元素一直在但内容是异步加载的等到空文本变成有内容才算真正“加载完成”。另一个容易忽略的“防抖”场景是点击“保存”按钮后前端会先提交请求可能还会弹出一个loading遮罩保存完成后遮罩消失。如果保存后马上断言某个表单消息弹出可能会撞上loading遮罩还没收起来的窗口期。稳妥做法是显式等待遮罩不可见WebDriverWait(driver, 10).until( EC.invisibility_of_element_located((By.CLASS_NAME, loading-mask)) )这类时序问题是UI自动化里最隐蔽也最消磨耐心的。我的经验是只要脚本出现“偶发失败”先怀疑等待条件不对而不是先怀疑定位错了。4. 用pytest构建可维护的自动化测试框架4.1 conftest.py中fixture的设计接着正式落地框架。第一步把浏览器初始化和回收逻辑收敛到conftest.py的fixture里。我维护一个init_driver# conftest.py import pytest from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager pytest.fixture def init_driver(): service Service(ChromeDriverManager().install()) options webdriver.ChromeOptions() options.add_argument(--start-maximized) driver webdriver.Chrome(serviceservice, optionsoptions) driver.implicitly_wait(5) yield driver driver.quit()yield取代return是实现“用例后清理”的关键。yield前的代码是setup——每个用例执行前创建浏览器并交给用例使用yield后的代码是teardown——用例结束后无论是成功还是失败都会关闭浏览器。这比在用例里try-finally手动清理要优雅得多。如果你的测试数据需要区分环境还可以写一个fixture从yaml或json读配置pytest.fixture def base_url(): return http://your-test-site.com # 可以改成从环境变量或配置文件读取4.2 数据驱动把测试数据从脚本里剥离开登录用例往往要覆盖多种组合正确账号、错误密码、空用户名、账号不存在等等。如果每个组合都写一个测试函数代码会爆炸而且测试数据和脚本逻辑搅在一起后续维护很痛苦。pytest的parametrize装饰器是解决这个问题的标准姿势import pytest pytest.mark.parametrize(username,password,expected_tip, [ (, 123456, 用户名不能为空), (admin, wrong, 用户名或密码错误), (admin, 123456, None), # 成功的用例expected_tip为None ]) def test_login_cases(init_driver, base_url, username, password, expected_tip): driver init_driver driver.get(base_url /login) login_page LoginPage(driver) login_page.login(username, password) if expected_tip: assert login_page.get_error_tip() expected_tip else: assert 欢迎 in driver.page_source这样一组数据就跑出三条用例报告里会分别展示出了错也能一眼定位是哪组数据的问题。当用例数量多了以后可以把数据挪到外部的yaml或json文件里用fixture读取后按参数循环传入这就是完整的数据驱动了。4.3 用例运行与报告生成框架搭好后执行测试pytest testcases -v --tbshort-v显示每个用例的详细结果--tbshort控制失败时回溯信息的长度不至于刷屏。想要输出HTML报告安装pytest-htmlpip install pytest-html pytest testcases --htmlreports/report.html --self-contained-html生成的报告是自包含的HTML文件可以直接发给团队成员看里面会展示每条用例的执行状态、失败原因、耗时等信息。如果你想拥有更精美的Allure报告体系搭配allure-pytest也能达到但那是另一个大话题了。我的建议是报告能看“成功/失败/失败原因/耗时”就够用了。很多团队把大量精力花在定制报告上面其实UI自动化最大的价值是帮你发现回归问题而不是比谁的报告好看。4.4 运行策略与CI集成本地调试阶段建议用-k参数精准筛选用例pytest testcases/test_login.py -k success or error -v全量回归时可以按模块并行执行。需要装pytest-xdistpip install pytest-xdist pytest testcases -n 4 # 4个进程并行并行执行会大幅缩短回归时间但要注意多个浏览器实例同时跑同一套数据时如果被测系统没有做并发隔离可能出现数据冲突。偶发性的脏数据比慢几秒更头疼所以并行之前先确认测试数据各用例间互不影响。CI集成方面我踩过的正经套路是把自动化任务挂到Jenkins或GitLab CI上提交代码后自动触发测试。这里有两个关键点CI环境通常没有显示器浏览器要开headless模式CI环境需要预装浏览器本体WebDriver Manager只能装驱动不能装浏览器。options.add_argument(--headless) options.add_argument(--no-sandbox) options.add_argument(--disable-dev-shm-usage)这三个参数是Linux无头环境的标配。--no-sandbox和--disable-dev-shm-usage是为了规避容器环境资源受限时Chrome崩溃的问题不加的话在Docker里跑非常容易一脸黑线。5. 实战中的典型问题与排查实录5.1 元素定位失败NoSuchElementException这大概是新手遇到最多的异常。排查顺序我从高到低排先看元素是不是在iframe里。用Chrome开发者工具选中元素看Element面板里有没有显示“iframe”祖先节点。有的话先用switch_to.frame切进去。再看是不是页面没加载完。隐式等待时间设短了或者异步内容还没渲染。先打开DevTools的Network面板确认接口返回状态再用显式等待增加缓冲。再看定位表达式是不是写死了。前端重构改了class名或id检查一下最新的DOM结构。最后看元素是不是有多个匹配。find_element永远返回第一个匹配元素如果目标其实在第2个位置你就控制错了对象。必要时用find_elements先取列表、按下标取值。5.2 元素被遮挡无法点击ElementClickInterceptedException这个异常字面意思很直白目标元素在DOM中存在但被其他元素挡住了浏览器拒绝点击。常见原因有三个一是弹窗遮罩层没关闭或还在动画中。处理办法是等待遮罩不可见或者按一下Esc键试试。二是页面有fixed定位的悬浮元素比如顶部推介条、客服浮窗盖住了按钮。这种在DevTools里很容易发现处理方式是先用execute_script滚动到元素位置再点击或者用JavaScript的click()绕过拦截element driver.find_element(By.ID, submitBtn) driver.execute_script(arguments[0].click();, element)这是非常实用的“曲线救国”方案但它绕过了真实用户的点击路径所以只在确认页面交互逻辑无碍的情况下使用。三是元素本身的disabled属性。这时候直接点击就会报拦截异常。需要等它变成可点击再用element_to_be_clickable条件去等。5.3 脚本不稳定偶发失败的排查思路脚本“时好时坏”是最消耗斗志的状态。我有一套固定的复盘流程先把失败现场留下来。浏览器截图和HTML快照是两个黄金证据# conftest.py 里挂一个失败截图钩子 import os import pytest pytest.hookimpl(hookwrapperTrue) def pytest_runtest_makereport(item, call): outcome yield report outcome.get_result() if report.when call and report.failed: driver item.funcargs.get(init_driver) if driver: os.makedirs(reports/screenshots, exist_okTrue) driver.save_screenshot(freports/screenshots/{item.name}.png)再看失败的时间点是统一集中在某一时刻还是随机分布。集中在同一时刻大概率是后端服务有定时任务或缓存刷新导致数据变化随机分布优先怀疑等待条件不够健壮。再看失败的用例归属是不是都集中在同一个页面模块。如果是那个页面很可能用了你没见过的交互组件需要重新走一遍手工操作流程记录下每一步的DOM状态。最后看数据影响用例是否依赖某些共享测试数据比如登录用同一个账号如果前一个用例把这个账号挤下线了后面的用例必挂。解决方案是用独立测试账号或每次登录前重置会话状态。5.4 浏览器驱动版本不匹配的坑Chrome浏览器会自动更新尤其默认开启自动更新的Windows和macOS今天还是120明天醒来可能就变121了而本地缓存的ChromeDriver还是120的启动时直接报SessionNotCreatedException: This version of ChromeDriver only supports Chrome version 120解决方案有两个方向。第一每次跑测试前主动检查驱动版本webdriver-manager在启动时会比对浏览器版本发现不匹配会重新下载。但它的判断逻辑有时不够即时稳妥做法是定期手动清一次驱动缓存# 清除webdriver-manager的缓存路径因系统而异 rm -rf ~/.wdm/drivers/chromedriver第二把浏览器的自动更新关掉用固定的企业版本配合锁定版本的驱动。这在测试环境可控的场景下是性价比很高的方案——稳定压倒一切新特性让开发环境去踩。5.5 无效定位器与等待时间过长的取舍有个操作习惯我特别推荐一个用例脚本写完后先把隐式等待全部改掉换成显式等待跑一遍看稳定性再把所有显式等待放到独立的“等待工具函数”里统一管理。这样调试时只需要改一个地方不需要翻遍整个项目找那几行裸等待。时间长了你会形成一套自己的“等待方法论”界面操作前等可点击数据加载等文本内容变化页面跳转等URL或标题变化。等待时间也不是越长越好。默认10秒已经是比较宽裕的如果某个操作需要超过10秒才能完成先怀疑是不是接口性能有问题而不是急着把超时时间调到30秒——那只是在掩盖问题。6. 最后的实操心得与进阶建议自动化测试这条路入门不难难的是“稳定”和“可维护”。我见过太多项目的自动化脚本刚写出来能跑一个版本迭代后就碎成一地最后不了了之。核心问题通常不在代码本身而在架构和习惯。给刚上手的朋友几条实实在在的建议都是我反复踩坑后的体会写自动化测试前先手工把核心业务流程完整走一遍。只有在手工操作时记录了每一步的页面状态、等待时长、异常提示你才可能写出靠谱的定位条件和等待策略。直接照着需求文档闷头写脚本大概率会被现实教育。等待优先用显式等待不要依赖强制休眠。但也不要走极端——个别场景下比如页面有ESLint报错导致控制台一直转圈强制等1到2秒反而比纠结等待条件更高效。工具是死的人是活的。元素定位信息不要散落在用例各处。统一收敛到Page类里或者至少收敛到一个locators模块。前端改动是常态把改动影响控制在一个文件里是自动化测试能活过三个迭代的前提。数据准备和清理必须提上日程。自动化测试跑得勤了会在被测系统里积累大量测试数据。你得有一个机制在测试结束后清理数据或在测试开始前用独立账号隔离数据。不解决数据问题脚本本身再稳定也会被脏数据拖垮。不要把断言写得过于细致。有些测试人员恨不得一个用例里断言十几次页面文本结果是前端任何文案微调都会导致用例失败而这些失败毫无价值。断言应该聚焦在业务核心状态上——登录是否成功、数据是否正确提交、状态是否变更细枝末节的文案变化不值得成为回归噪声。等到你把Selenium这套体系摸透了下一步建议去了解一下Playwright的自动等待与网络拦截机制对比着用会很有启发再往深走可以把Requests直接调接口做数据准备、再用Selenium验证界面展示接口加UI双层配合自动化覆盖率会大幅提升。UI自动化不是万能的但掌握它你的测试工具箱会完整一大截。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Kettle 9.5从安装到调度:ETL避坑实战指南 2026/10/1 17:36:25

Kettle 9.5从安装到调度:ETL避坑实战指南

简介:这是一份由作者自编译的 Pentaho Kettle 9.5 数据集成工具包(PDI-CE-9.5.0.1-261),面向需要快速搭建数据抽取、转换、加载流程的中高级 ETL 开发人员。工具基于 JDK 17 构建,支持苹果 M1 芯片、Windows 与 Linux …

阅读更多 →
私有AI平台实战:Dify+Ollama+DeepSeek混合部署降本指南 2026/10/1 17:36:25

私有AI平台实战:Dify+Ollama+DeepSeek混合部署降本指南

说真的,我第一次看到那个 API 账单时,人都是麻的。几个自己写的脚本、一个给同事用的小工具、一个跑在群里自动答话的机器人,一个月下来 token 费用滚得比我的咖啡钱还高,而且所有数据都从别人服务器上过了一遍,心里始…

阅读更多 →
Z-EVES实战:从Z规格到证明义务的形式化验证指南 2026/10/1 17:36:18

Z-EVES实战:从Z规格到证明义务的形式化验证指南

简介:面向形式化Z语言学习者的实用工具包,整合Z-EVES辅助工具与配套文档,适合软件工程师、研究人员及航空航天、医疗、金融等安全关键领域开发者,用于Z规格的编写、验证与代码生成。压缩包共5个文件,整体约8.63MB&…

阅读更多 →
基于SpringBoot+RabbitMQ+Redis的私信系统架构设计与实战 2026/10/1 17:36:18

基于SpringBoot+RabbitMQ+Redis的私信系统架构设计与实战

私信系统这东西,看着功能简单,不就是"你发一条、我收一条"嘛。可真要在一个日活几十万的社交平台上落地,从消息不丢、不乱序,到已读回执实时同步,再到历史消息秒开不卡顿,每一环都是坑。我去年完…

阅读更多 →
Typora与Obsidian共存:一套统一规范搞定笔记迁移与知识库管理 2026/10/1 17:36:18

Typora与Obsidian共存:一套统一规范搞定笔记迁移与知识库管理

如果你跟我一样,先花了两三年时间用 Typora 写笔记、写博客草稿、记项目文档,后来又因为双链、知识库管理的需求开始用 Obsidian,那你大概率会撞上同一个尴尬:两个编辑器默认的格式习惯完全不同,图片路径、链接语法、标…

阅读更多 →
AI建模实战:从数学建模到3D打印的完整尝试与避坑指南 2026/10/1 17:36:18

AI建模实战:从数学建模到3D打印的完整尝试与避坑指南

1. 这次为什么还要“继续尝试”“继续尝试AI建模”这句话,说白了就是我自己的真实状态。第一次玩AI建模的时候,我以为扔几句话进去就能拿到一个能用的模型,结果折腾几天,得到的全是“看起来很专业”但根本没法落地的半成品。当时差…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉