Selenium2Library高级技巧:构建健壮高效的Robot Framework UI自动化测试

📅 2026/7/4 21:54:14
Selenium2Library高级技巧:构建健壮高效的Robot Framework UI自动化测试
1. 项目概述为什么我们需要Selenium2Library的高级技巧如果你正在用Robot Framework做UI自动化测试并且已经熟练掌握了Click Element、Input Text这些基础关键字那么恭喜你你已经成功迈出了第一步。但很快你就会遇到一些更“磨人”的问题测试脚本在本地跑得好好的一到CI/CD流水线就间歇性失败页面加载慢一点元素定位就报错处理动态弹窗和iframe手忙脚乱测试报告里除了“PASS”和“FAIL”看不出任何有价值的上下文信息。这些问题正是基础API无法覆盖的“深水区”。Selenium2Library是Robot Framework生态中用于Web自动化的核心库它封装了Selenium WebDriver的能力。但仅仅会调用它的关键字就像只学会了汽车的油门和刹车远谈不上“老司机”。真正的效率与稳定性提升来自于对浏览器行为、网络环境、框架机制和工程实践的深度理解与巧妙运用。本文分享的10个高级技巧并非来自官方文档的简单罗列而是我在多年实战中从无数次的脚本调试、性能优化和稳定性攻坚中提炼出的“生存法则”。它们的目标很明确让你的自动化测试脚本从“能跑”变得“健壮、高效、易维护”真正成为研发流程中值得信赖的一环。2. 技巧一构建坚如磐石的“智能等待”策略几乎所有不稳定的UI自动化脚本第一个病根都出在“等待”上。Sleep 5s这种简单粗暴的方式是万恶之源它让测试时间不可控且极度低效。Selenium2Library提供了Wait Until系列关键字但如何用好它们才是关键。2.1 理解等待的三种境界硬性等待Sleep死等固定时间。除非模拟人类思考停顿且不推荐否则应避免使用。隐式等待Implicit Wait通过Set Selenium Implicit Wait设置一个全局超时时间。WebDriver在查找任何元素时如果没立即找到会轮询DOM直到超时。它的最大问题是只对Find Element类操作有效对元素状态如是否可点击、是否可见无效且会拖慢所有元素查找。我的建议是要么不用要么设一个很小的值如2秒作为安全网。显式等待Explicit Wait针对特定条件进行等待条件满足则立即继续超时则报错。这是稳定性保障的基石。Selenium2Library的Wait Until Page Contains、Wait Until Element Is Visible等都属于此类。2.2 设计分层等待策略不要只依赖单一的关键字。我通常构建一个三层等待策略*** Settings *** Library Selenium2Library timeout10s implicit_wait2s # 第一层库级别全局超时和隐式等待安全网 *** Keywords *** 智能等待元素可操作 [Arguments] ${locator} # 第二层核心显式等待 - 等待元素存在且可见 Wait Until Element Is Visible ${locator} timeout15s error元素“${locator}”在15秒内未变得可见 # 第三层额外状态检查 - 等待元素可交互非必须针对复杂UI ${is_enabled} Run Keyword And Return Status Element Should Be Enabled ${locator} Run Keyword If not ${is_enabled} Fail 元素“${locator}”可见但处于禁用状态无法操作实操心得timeout参数不要一刀切。对于主要页面加载可以设10-15秒对于一个普通的按钮5秒可能就够了。超时信息error一定要自定义这样失败时能立刻知道是哪个元素出了问题而不是一个笼统的“TimeoutException”。2.3 自定义等待条件应对极端场景有些场景内置关键字不够用比如等待某个元素的特定属性值变化或者等待页面某个JavaScript变量被赋值。这时就需要用到Wait Until Keyword Succeeds这个“万能钥匙”。等待订单状态变为“已完成” # 每隔2秒检查一次最多等待30秒直到条件满足 Wait Until Keyword Succeeds 30s 2s 订单状态应为已完成 订单状态应为已完成 ${status} Get Text css.order-status Should Be Equal As Strings ${status} 已完成注意Wait Until Keyword Succeeds内部的检查关键字如果失败会抛出异常并被捕获然后重试。因此这个内部关键字必须能在失败时抛出异常比如使用Should系列断言而不是静默返回False。3. 技巧二高级定位器策略与动态元素处理定位器Locator是自动化脚本的“眼睛”。id和name是最优选择但现实项目中面对层出不穷的动态ID和复杂组件我们必须掌握更强大的定位技术。3.1 优先使用CSS Selector而非XPath虽然Selenium2Library两者都支持但在绝大多数情况下CSS Selector的性能和可读性都优于XPath。浏览器原生支持CSS查询速度更快。XPath://div[idcontainer]//button[contains(text(), 提交)]CSS (更优):cssdiv#container button:contains(提交)(注意:contains是jQuery扩展标准CSS需用其他方法) 更标准的做法是结合其他属性cssdiv#container button[typesubmit]对于简单的属性匹配CSS非常简洁Input Text cssinput[nameusername] myUser Click Element cssbutton.btn-primary3.2 处理动态ID和类名现代前端框架如React、Vue常生成动态ID如idinput-12345。不要尝试定位完整的动态值。使用属性部分匹配# 使用CSS的属性开头匹配 Click Element css[id^input-] # 使用XPath的contains函数 Click Element xpath//*[contains(id, input-)]寻找稳定的父容器再向下定位如果元素本身动态但其父级或兄弟元素是稳定的可以先定位稳定元素再使用相对定位。# 假设有一个稳定的标题栏其下的按钮是动态的 ${parent} Get Webelement xpath//h2[text()用户列表] # 使用XPath轴定位下一个兄弟节点里的按钮 Click Element xpath${parent}/following-sibling::div//button3.3 使用Get Webelement与链式调用当定位步骤复杂或需要复用某个元素对象时直接获取WebElement对象再进行操作会更灵活高效。*** Keywords *** 获取用户表格第一行的编辑按钮 ${table} Get Webelement css.user-data-table # 在找到的table元素内部继续查找避免全局搜索更精准快速 ${first_row} Get Webelement ${table} tagtr ${edit_button} Get Webelement ${first_row} cssbutton.edit-btn [Return] ${edit_button} 测试用例示例 ${btn} 获取用户表格第一行的编辑按钮 Click Element ${btn} # 直接操作WebElement对象 # 还可以获取该元素的更多属性 ${text} Get Text ${btn} Log 编辑按钮的文本是${text}这种方法将复杂的定位逻辑封装在关键字内部让测试用例更清晰也提高了定位的复用性和精度。4. 技巧三利用JavaScript执行突破Selenium的限制Selenium WebDriver的API虽然强大但终究受限于浏览器安全策略和标准交互模型。有些操作比如直接修改元素属性、触发非标准事件、执行复杂DOM查询或获取浏览器性能数据需要通过执行JavaScript来实现。4.1Execute JavaScript关键字的妙用Execute JavaScript关键字让你能在当前页面的上下文中执行任意JS代码并将结果返回给Robot Framework。场景1直接修改元素属性或值有时候前端设置了输入框的readonly属性或者用自定义组件屏蔽了直接输入。你可以用JS绕过。# 将输入框设置为可编辑并输入值 Execute JavaScript document.querySelector(#readonly-input).removeAttribute(readonly); Input Text idreadonly-input 新的内容 # 或者更直接地设置值不触发input事件 Execute JavaScript arguments[0].value 直接设置的值; ARGUMENTS ${input_element}场景2触发复杂的事件有些自定义组件需要触发特定事件才能响应。# 模拟鼠标悬停 ${element} Get Webelement css.dropdown-toggle Execute JavaScript arguments[0].dispatchEvent(new MouseEvent(mouseover, {bubbles: true})); ARGUMENTS ${element}场景3获取页面性能数据或复杂状态# 获取页面加载时间Navigation Timing API ${load_time} Execute JavaScript return performance.timing.loadEventEnd - performance.timing.navigationStart; Log 页面完全加载耗时${load_time} 毫秒 # 检查jQuery Ajax是否正在进行 ${ajax_active} Execute JavaScript return (typeof jQuery ! undefined) jQuery.active 0; Run Keyword If ${ajax_active} Log 页面尚有Ajax请求未完成4.2 封装常用JS操作为自定义关键字为了提高可读性和复用性将常用的JS操作封装起来。*** Keywords *** 滚动到元素并居中 [Arguments] ${locator} ${element} Get Webelement ${locator} Execute JavaScript ... arguments[0].scrollIntoView({behavior: smooth, block: center}); ... ARGUMENTS ${element} 设置本地存储项 [Arguments] ${key} ${value} ${json_value} Evaluate json.dumps(${value}) json Execute JavaScript localStorage.setItem(${key}, ${json_value});重要警告虽然JS执行很强大但切勿滥用。它破坏了测试对真实用户操作的模拟。优先使用标准的Selenium交互关键字Click, Input等。仅在标准方法无法实现、或需要获取内部状态进行断言时才使用JS作为补充手段。同时注意JS执行是同步的对于大量操作可能阻塞页面。5. 技巧四精通浏览器驱动与多窗口/Frame导航Web应用不再是简单的单页弹窗、iframe、多标签页是常态。处理不好这些脚本就会卡死或定位错误。5.1 稳健的Frame和Iframe切换进入和离开Frame必须成对出现否则后续定位都会在错误的上下文中进行。处理登录iframe # 1. 首先确保在主页面 Unselect Frame # 可选确保回到默认顶层 # 2. 定位并切换到iframe Select Frame cssiframe[namelogin-frame] # 3. 在iframe内部操作 Input Text idusername testuser Input Text idpassword testpass Click Button 登录 # 4. 操作完成后必须切回主文档 Unselect Frame # 现在可以继续操作主页面的元素了 Page Should Contain 登录成功常见坑点如果iframe是动态加载的必须在Select Frame前使用Wait Until Element Is Visible等待iframe出现。切换回主文档后如果后续操作需要等待主页面的元素同样要加上等待因为切换上下文后页面可能还在变化。5.2 多窗口标签页的精准操控点击一个链接可能打开新标签页你需要能准确地在窗口间切换。点击链接打开新窗口并验证 ${main_window} Get Window Handle # 获取当前主窗口句柄 Click Link cssa[target_blank] # 点击打开新窗口的链接 # 等待新窗口出现 Wait Until Keyword Succeeds 5s 1s 新窗口应已打开 # 切换到新窗口 Switch Window NEW # 在新窗口操作 Title Should Be 新页面标题 # ... 执行一些测试 ... Close Window # 关闭新窗口 # 切回主窗口 Switch Window ${main_window} # 继续主窗口的操作 新窗口应已打开 ${handles} Get Window Handles Should Be True len(${handles}) 1实操心得Get Window Handle单数返回当前活动窗口的句柄。Get Window Handles复数返回所有打开窗口的句柄列表。Switch Window可以使用NEW最新窗口、MAIN最初窗口或具体的窗口句柄。最佳实践是在打开新窗口前先保存主窗口句柄像锚点一样确保总能切回来。5.3 浏览器日志与网络控制高级对于调试或需要验证前端错误、网络请求的场景可以配置浏览器驱动来获取日志或模拟网络条件。*** Settings *** Library Selenium2Library *** Test Cases *** 示例获取浏览器控制台日志 Open Browser https://example.com chrome ... desired_capabilities${DESIRED_CAPS} # 需要通过desired_capabilities开启日志 *** Variables *** ${DESIRED_CAPS} Evaluate {goog:loggingPrefs: {browser: ALL, performance: ALL}}之后你可以使用Get Log关键字注意不同浏览器支持不同来获取日志内容分析JS错误或警告。这在对前端质量有要求的测试中非常有用。6. 技巧五数据驱动测试与动态测试用例生成当需要用多组数据测试同一个业务流程时手动复制粘贴测试用例是低效且难以维护的。Robot Framework内置了强大的数据驱动测试能力。6.1 使用Template和Test Template标签这是最直接的数据驱动方式。将一个关键字设置为测试用例的模板该用例下的每一行数据都会作为一次独立的测试执行。*** Settings *** Test Template 登录测试模板 *** Test Cases *** 用户名 密码 预期结果 无效登录测试用例 invalid_user wrong_pass 登录失败 empty_user ${EMPTY} 登录失败 valid_user ${EMPTY} 登录失败 *** Keywords *** 登录测试模板 [Arguments] ${username} ${password} ${expected_result} Go To Login Page Input Username ${username} Input Password ${password} Click Login Button Run Keyword If ${expected_result} 登录成功 ... Page Should Contain 欢迎回来 ... ELSE ... Page Should Contain 用户名或密码错误这种方式清晰地将测试数据与逻辑分离报告会显示每个数据行的执行结果。6.2 利用外部数据文件CSV, Excel, 数据库对于大量、复杂的数据最好将数据存储在外部文件中。*** Settings *** Library DataDriver filelogin_data.csv encodingutf-8-sig Test Template 通用登录测试 *** Test Cases *** 使用CSV数据驱动登录测试 ${username} ${password} ${expected} *** Keywords *** 通用登录测试 [Arguments] ${username} ${password} ${expected} # ... 登录逻辑 ... Should Contain ${actual_result} ${expected}你需要安装DataDriver库 (pip install robotframework-datadriver)。CSV文件login_data.csv内容如下username,password,expected user1,pass1,登录成功 user2,wrong,登录失败 ,pass3,登录失败6.3 动态生成测试用例有时测试用例本身需要根据运行时的环境或数据动态决定。可以使用Run Keyword If、For循环结合Set Test Variable或Set Suite Variable来实现一定程度的动态性但更复杂的动态生成需要借助robot变量文件或自定义的测试库在初始化阶段生成用例。一个简单的动态循环示例*** Test Cases *** 测试多个搜索关键词 {keywords} Create List Robot Framework Selenium Python Automation FOR ${keyword} IN {keywords} Log 正在测试关键词: ${keyword} 执行搜索并验证 ${keyword} END注意这仍然是一个测试用例。如果循环中某次失败整个用例就失败了。对于需要完全独立报告和数据隔离的场景外部数据驱动是更好的选择。7. 技巧六自定义关键字的艺术与封装策略当你的测试套件越来越大时维护一堆直接调用Selenium2Library关键字的测试用例会是一场噩梦。自定义关键字是提升可维护性、复用性和可读性的核心手段。7.1 设计高内聚、低耦合的关键字一个好的自定义关键字应该像一个小函数只做一件事并且做好。反面教材一个叫完成用户注册的关键字里面包含了打开浏览器、导航到注册页、填写10个字段、点击提交、检查邮件、登录验证……这太长了难以复用和调试。正面教材*** Keywords *** 导航到注册页面 Go To ${REGISTER_URL} 等待注册表单加载完成 填写必填用户信息 [Arguments] ${username} ${email} ${password} Input Text idusername ${username} Input Text idemail ${email} Input Text idpassword ${password} 提交注册表单 Click Button cssbutton[typesubmit] 等待页面跳转完成 验证注册成功提示 Wait Until Page Contains 注册成功 Page Should Contain Element css.success-message # 高层级业务关键字 完成用户注册流程 [Arguments] ${user_data} 导航到注册页面 填写必填用户信息 {user_data}[username] {user_data}[email] {user_data}[password] 提交注册表单 验证注册成功提示这样填写必填用户信息可以被其他测试如编辑用户信息复用。高层级关键字组合了低层级操作读起来就像自然语言。7.2 使用参数和返回值充分利用[Arguments]和[Return]让关键字更灵活。获取订单总金额并格式化 [Arguments] ${订单号} ${金额元素} Get Webelement xpath//tr[td[contains(text(),${订单号})]]/td[classamount] ${原始文本} Get Text ${金额元素} ${清理后文本} Remove String ${原始文本} $ , # 移除美元符号和逗号 ${浮点数} Convert To Number ${清理后文本} [Return] ${浮点数} # 在测试用例中使用 ${订单金额} 获取订单总金额并格式化 ORD-2023-001 Should Be True ${订单金额} 100.07.3 创建资源文件与变量文件将通用的关键字和变量抽取到独立的资源文件.resource和变量文件.py或.yaml中是大型项目架构的关键。common_keywords.resource: 存放等待元素可操作、安全点击、截图并附加到日志等通用关键字。page_objects.resource: 存放按页面组织的关键字如LoginPage.robot、DashboardPage.robot实现Page Object模式。config.py: 用Python定义变量可以执行逻辑。# config.py import os BASE_URL os.getenv(TEST_BASE_URL, https://staging.example.com) BROWSER os.getenv(TEST_BROWSER, chrome) IMPLICIT_WAIT int(os.getenv(IMPLICIT_WAIT, 5))在Robot文件中引用*** Settings *** Resource common_keywords.resource Resource pages/LoginPage.resource Variables config.py这种架构使得底层UI定位符变化时只需修改对应的资源文件所有测试用例都自动受益。8. 技巧七异常处理与失败场景的优雅恢复自动化测试不可能永远一帆风顺。网络抖动、环境差异、临时弹窗都会导致失败。一个健壮的测试脚本应该能处理预期内的异常并提供清晰的失败信息甚至尝试恢复。8.1 使用Run Keyword And Ignore Error与Run Keyword And Return Status这两个关键字是处理“可接受失败”或“条件检查”的利器。Run Keyword And Return Status: 执行一个关键字返回True成功或False失败不抛出异常。用于条件判断。${登录框可见} Run Keyword And Return Status Page Should Contain Element idlogin-modal Run Keyword If ${登录框可见} Click Element css.modal-close # 如果有弹窗关闭它Run Keyword And Ignore Error: 执行一个关键字返回一个包含状态PASS/FAIL和消息或返回值的列表。当你不关心关键字是否失败但需要知道结果时使用。${status} ${message} Run Keyword And Ignore Error Click Element cssunstable-button Run Keyword If ${status} FAIL Log 按钮点击失败可能未加载尝试备用方案 WARN ... ELSE Log 按钮点击成功8.2 实现“安全点击”和“安全输入”关键字将等待、重试和异常处理封装到基础操作中能极大提升脚本稳定性。*** Keywords *** 安全点击元素 [Arguments] ${locator} ${timeout}10s [Documentation] 点击元素如果失败尝试滚动到视图再点击并记录详细日志。 Wait Until Element Is Visible ${locator} timeout${timeout} Scroll Element Into View ${locator} ${click_status} ${msg} Run Keyword And Ignore Error Click Element ${locator} Run Keyword If ${click_status} FAIL ... Run Keywords ... Log 标准点击失败尝试通过JavaScript点击: ${msg} WARN ... AND Execute JavaScript arguments[0].click(); ARGUMENTS ${locator} ... ELSE ... Log 元素 ${locator} 点击成功。 安全输入文本 [Arguments] ${locator} ${text} ${clear_first}${True} Wait Until Element Is Visible ${locator} Scroll Element Into View ${locator} Run Keyword If ${clear_first} Clear Element Text ${locator} # 有时Clear后直接Input会失败先点击一下激活 Click Element ${locator} Input Text ${locator} ${text}8.3 设置全局的测试Teardown和Suite Setup利用Test Teardown和Suite Teardown确保无论测试成功还是失败都能执行一些清理工作比如关闭浏览器、清理测试数据、发送通知等。*** Settings *** Suite Setup 全局测试准备 Suite Teardown 全局测试清理 Test Setup 打开测试浏览器 Test Teardown Run Keywords 捕获失败截图 AND 关闭测试浏览器 *** Keywords *** 捕获失败截图 Run Keyword If Test Failed Capture Page Screenshot filenameFAILURE-{TEST NAME}-{index}.pngRun Keyword If Test Failed是一个非常有用的内置关键字它只在测试用例失败时才执行其中的操作。9. 技巧八测试报告与日志的增强与定制默认的Robot Framework报告和日志已经很详细但我们可以做得更好让问题定位更快。9.1 使用Log和Log To Console输出关键信息在关键步骤添加有意义的日志而不是依赖自动生成的步骤记录。登录到管理员后台 Log 正在尝试登录管理员账户... consoleTrue # 同时输出到控制台便于实时查看 Input Text idusername ${ADMIN_USER} Input Text idpassword ${ADMIN_PASS} ${点击前URL} Get Location Click Button 登录 Wait Until Location Contains /admin/dashboard timeout15s ${点击后URL} Get Location Log 登录成功从 ${点击前URL} 跳转至 ${点击后URL} levelINFOconsoleTrue在长时间运行的测试中非常有用你可以从CI/CD工具的实时输出中看到进度。9.2 为失败断言提供自定义错误信息所有Should系列的断言关键字都支持自定义错误信息。Page Should Contain 订单创建成功 ... error页面未找到‘订单创建成功’提示当前页面内容为${CURPAGE_CONTENT}当断言失败时这个自定义的错误信息会直接显示在报告和日志中省去你再去查看页面源码的步骤。你可以创建一个关键字来自动获取当前页面的部分文本作为错误信息的一部分。9.3 集成Allure等高级报告框架对于大型项目可以考虑集成Allure报告它能生成更美观、交互性更强的测试报告支持附件截图、日志、步骤描述、标签分类等。安装依赖pip install allure-robotframework在测试中标记*** Settings *** Library allure_robotframework *** Test Cases *** 示例测试用例 [Tags] smoke login Allure Description 这是一个验证用户登录功能的冒烟测试用例。 Log 开始登录测试 levelINFO # ... 测试步骤 ... Run Keyword If Test Failed Allure Attach File ${SCREENSHOT_PATH} name失败截图运行测试时添加--listener allure_robotframework参数生成Allure结果文件然后用Allure命令行工具生成HTML报告。10. 技巧九与CI/CD流水线的深度集成自动化测试的价值在持续集成/持续部署CI/CD中才能最大化体现。集成不仅仅是“能跑”更要“跑得稳”、“报告清”、“失败快”。10.1 无头模式与远程执行在CI服务器上通常没有图形界面需要使用无头Headless模式。*** Settings *** Library Selenium2Library *** Variables *** ${HEADLESS} ${True} # 通过环境变量控制 *** Keywords *** 打开测试浏览器 ${options} Evaluate sys.modules[selenium.webdriver].ChromeOptions() sys Run Keyword If ${HEADLESS} Call Method ${options} add_argument --headlessnew Call Method ${options} add_argument --disable-gpu Call Method ${options} add_argument --no-sandbox # Docker等容器环境常用 Call Method ${options} add_argument --disable-dev-shm-usage # 解决共享内存问题 Create Webdriver Chrome chrome_options${options} Set Selenium Implicit Wait 5s Maximize Browser Window使用Create Webdriver可以更精细地控制浏览器选项。--headlessnew是Chrome较新版本的推荐参数。10.2 使用Selenium Grid进行分布式测试当测试套件很大时可以利用Selenium Grid在多台机器、多个浏览器上并行运行测试极大缩短反馈时间。启动Grid Hub和Node。在Robot Framework中使用Open Browser时指定远程地址和所需能力Desired Capabilities。Open Browser https://example.com browserchrome ... remote_urlhttp://grid-hub:4444/wd/hub ... desired_capabilitiesbrowserName:chrome, platform:LINUX你可以通过变量控制remote_url使得同一套脚本可以在本地连接http://localhost:4444和CI环境连接真正的Grid Hub无缝切换。10.3 测试结果的处理与通知CI流水线需要根据测试结果决定是否继续部署。结果输出使用--outputdir指定输出目录使用--log、--report、--xunit生成不同格式的报告。XUnit格式的报告容易被Jenkins等CI工具解析。robot --outputdir results --log mylog.html --report myreport.html --xunit xunit.xml my_tests/失败处理在CI脚本中检查Robot的退出码0表示所有测试通过非0表示有失败。可以配置在测试失败时自动重跑失败的用例使用--rerunfailed选项。通知集成Slack、Teams或邮件通知在测试失败时第一时间通知相关人员。可以编写一个后处理脚本解析output.xml提取失败信息并发送。11. 技巧十性能优化与脚本维护性提升当你有成百上千个测试用例时执行速度和维护成本就成为关键问题。11.1 优化测试套件结构按功能模块划分套件不要把所有测试用例放在一个.robot文件里。按登录、订单、用户管理等模块划分便于并行执行和定位问题。使用标签Tags进行灵活筛选为测试用例打上smoke冒烟、regression回归、slow慢速等标签。*** Test Cases *** 快速登录测试 [Tags] smoke login # ... 步骤 ... 完整的用户旅程测试 [Tags] regression e2e slow # ... 步骤 ...运行时可以只跑冒烟测试robot --include smoke tests/或者排除慢速测试robot --exclude slow tests/。11.2 减少不必要的浏览器启动浏览器启动和关闭是耗时操作。对于一组紧密相关的测试用例可以考虑使用Suite Setup打开一次浏览器在Suite Teardown中关闭而不是每个用例都开关Test Setup/Test Teardown。但这需要确保测试用例之间是独立的不会相互影响状态如cookie、localStorage。通常更推荐每个测试用例独立运行以避免状态污染虽然牺牲了一些时间但获得了更高的稳定性和可并行性。可以通过Selenium Grid并行执行来弥补时间损失。11.3 定期重构与代码审查自动化测试代码也是代码需要像对待生产代码一样进行维护。定期重构删除重复代码更新过时的定位器优化等待策略。进行代码审查在团队中对测试脚本的修改也应进行代码审查确保遵循共同的编码规范关键字设计合理。建立定位器仓库对于大型项目可以考虑将页面元素的定位器统一管理在一个变量文件中任何定位器的更改只需在一处进行。# locators.py LOGIN { 用户名输入框: idusername, 密码输入框: idpassword, 登录按钮: cssbutton.login-btn, 错误提示: css.alert-error }*** Settings *** Variables locators.py *** Test Cases *** 测试登录 Input Text ${LOGIN}[用户名输入框] user1 Input Text ${LOGIN}[密码输入框] pass1 Click Element ${LOGIN}[登录按钮]11.4 监控与告警将自动化测试的通过率、执行时长、稳定性如Flaky Tests——时过时不过的测试纳入监控。定期分析失败原因如果是产品Bug就提缺陷如果是测试脚本不稳定就优化脚本如果是环境问题就改善环境。让自动化测试成为一个持续反馈和优化的闭环系统而不仅仅是一个被定时执行的任务。