- 测试
- RPA
- 接口测试
【免费下载链接】robotframework
Generic automation framework for acceptance testing and RPA
导读
本篇技术指南围绕 AdvancedFeatures.rst 展开,系统讲解 Robot Framework 中三个易被忽视却至关重要的高级特性:同名关键词的冲突解析机制(作用域优先级、全名限定与Set Library Search Order)、测试用例与用户关键词的超时控制,以及在库层面实现的关键词并行执行模式。读完本文,你将能够精准控制多库、多资源环境下关键词的解析顺序,正确配置测试与关键词级超时以防范挂起,并掌握基于Process库的标准并行执行套路。
一、同名关键词的冲突处理
Robot Framework 中的关键词分为两类:来自标准库或外部库的library keywords(库关键词),以及创建于套件文件本身或从资源文件导入的user keywords(用户关键词)。当项目规模变大、导入的库与资源增多时,同名关键词几乎不可避免。本节介绍 Robot Framework 如何处理这些冲突。
1.1 关键词作用域(Keyword scopes)优先级
当测试数据中只使用关键词短名(即不带库/资源前缀)时,Robot Framework 依据关键词的创建来源决定其作用域优先级,顺序如下:
- 当前套件文件中创建的用户关键词——优先级最高,无论其他位置是否存在同名关键词,始终被使用。
- 资源文件中创建的关键词(直接或间接从其他资源文件导入)——第二优先级。
- 外部测试库中的关键词——第三优先级;若没有同名用户关键词则被使用,但如果标准库中存在同名关键词,会显示一条警告。
- 标准库中的关键词——优先级最低。
这一优先级规则在源码中有明确体现。namespace.py 的_get_runner方法按固定顺序查找:
def _get_runner(self, name, strip_bdd_prefix=True): ... runner = self._get_runner_from_suite_file(name) # 1. 当前套件文件的用户关键词 if not runner and '.' in name: runner = self._get_explicit_runner(name) # 2. 显式全名限定(见 1.2) if not runner: runner = self._get_implicit_runner(name) # 3. 隐式查找资源文件 → 库 return runner其中_get_implicit_runner依次尝试资源文件和库(namespace.py):
def _get_implicit_runner(self, name): return (self._get_runner_from_resource_files(name) or self._get_runner_from_libraries(name))此外,当多个库关键词同名时,_get_runner_from_libraries内部还会通过_filter_stdlib_handler(namespace.py)处理"自定义库与标准库冲突"的情况:若冲突双方恰好是某个标准库(如BuiltIn、String等,排除Remote)与自定义库,则优先使用自定义库关键词,并发出形如"Keyword 'X' found both from a custom library ... and a standard library ... The custom keyword is used."的警告,提示用户可以用全名显式选择。
1.2 使用全名显式指定关键词
作用域机制只能解决"谁优先"的问题,当多个库或多个资源之间存在同名关键词时,就需要显式指定关键词的全名:在关键词名前加上库名或资源名,以点号.分隔。
- 库关键词:格式为
LibraryName.Keyword Name。例如 OperatingSystem 库的Run关键词,即使其他地方存在另一个Run,也可用OperatingSystem.Run精确调用。 - 模块或包形式的库:必须使用完整的模块名或包名,例如
com.company.Library.Some Keyword。 - 自定义库名:如果导入库时通过
AS指定了自定义名称,全名中必须使用该自定义名称。 - 资源文件:资源名取自资源文件的基本文件名(不含扩展名)。例如资源文件
myresources.html中的关键词Example,可用myresources.Example调用。 - 同名资源文件限制:若有多个资源文件具有相同的基本文件名,此语法无法区分,必须重命名文件或关键词。
- 大小写/空格/下划线不敏感:全名与普通关键词名一样,对大小写、空格和下划线不敏感。
从源码看,_get_explicit_runner(namespace.py)会解析全名中的点号,枚举所有可能的"所有者名 + 关键词名"组合,在库与资源中精确匹配;_get_owner_and_kw_names(namespace.py)把full_name按点号拆分成多种前缀组合再逐一尝试,因此像com.company.Library.Some Keyword这种多段全名也能正确解析。
1.3 用Set Library Search Order显式设定解析顺序
当冲突较多时,逐个使用全名是繁琐的,且全名写法会让动态测试用例或用户关键词无法根据可用库/资源灵活切换。解决方案是使用 BuiltIn 库的Set Library Search Order关键词显式指定优先级。
*** Settings *** Library MyLibrary Library YourLibrary Resource myresources.resource *** Test Cases *** Example Set Library Search Order MyLibrary myresources Some Keyword argument其行为要点(来自 BuiltIn.py 的关键词文档):
- 接受一个有序的库/资源列表。当关键词名匹配多个实现时,第一个包含该关键词的库或资源被选中。
- 若关键词在所有指定库/资源中都找不到,执行方式与未设置搜索顺序时相同(报错失败)。
- 注意:尽管关键词名含 "Library",它也适用于资源文件;但资源文件中的关键词永远优先于库中的关键词,不受搜索顺序影响。
- 搜索顺序仅在当前套件内有效;调用该关键词会返回旧顺序,可用于之后恢复;不带参数调用则清除搜索顺序;库名与资源名同样大小写、空格不敏感。
- 设置后无需再使用
LibraryName.Keyword Name长格式。
底层实现中,set_library_search_order调用self._namespace.set_search_order(search_order)(BuiltIn.py),将新顺序写入KeywordStore.search_order(namespace.py),默认值为空元组(namespace.py)。在隐式解析时,_filter_based_on_search_order(namespace.py)按顺序依次用eq(name, kw.owner.name)比对所有者名称,命中即返回该组关键词:
def _filter_based_on_search_order(self, keywords): for name in self.search_order: matches = [kw for kw in keywords if eq(name, kw.owner.name)] if matches: return matches return keywords该函数同时被_get_runner_from_resource_files和_get_runner_from_libraries调用,验证了"资源与库均可参与搜索顺序"的设计。
二、超时控制(Timeouts)
有些关键词可能执行异常缓慢甚至无限挂起。Robot Framework 允许为测试用例和用户关键词设置超时,一旦超时,当前正在执行的关键词会被强制停止。需要强调的是,这种强制停止可能使库、测试环境或被测系统进入不稳定状态,因此仅在没有更安全方案时推荐使用;库的实现应尽量避免关键词挂起,或自带超时机制。
2.1 测试用例超时(Test case timeout)
测试用例超时可通过两种方式设置:
Test Timeout设置(Settings 表):为该套件内所有测试用例定义默认超时;[Timeout]设置(单个测试用例内):为特定用例设置超时,并覆盖默认值。
关键规则:
- 空
[Timeout]表示该测试无超时(即使已设置Test Timeout);也可显式使用NONE达到同样目的。 - 超时值为0 或负数时同样被忽略。
- 超时值必须使用 Robot Framework 的时间格式(
TimeFormat):可以是纯秒数如10,也可以是1 minute 30 seconds这种描述性格式;还支持使用变量(例如从命令行传入${TIMEOUT})。 - 超时触发:正在运行的关键词被停止,测试用例失败;但测试 teardown 中执行的关键词不会被测试超时打断,测试仍标记为失败。若 teardown 中的关键词可能挂起,应改用用户关键词超时(见 2.2)。
完整示例:
*** Settings *** Test Timeout 2 minutes *** Test Cases *** Default timeout [Documentation] Default timeout from Settings is used. Some Keyword argument Override [Documentation] Override default, use 10 seconds timeout. [Timeout] 10 Some Keyword argument Variables [Documentation] It is possible to use variables too. [Timeout] ${TIMEOUT} Some Keyword argument No timeout [Documentation] Empty timeout means no timeout even when Test Timeout has been used. [Timeout] Some Keyword argument No timeout 2 [Documentation] Disabling timeout with NONE works too and is more explicit. [Timeout] NONE Some Keyword argument2.2 用户关键词超时(User keyword timeout)
用户关键词同样支持用[Timeout]设置超时,语法与测试用例超时完全一致,但没有默认值。如果超时值由变量指定,还可以作为关键词参数传入。
*** Keywords *** Hardcoded [Arguments] ${arg} [Timeout] 1 minute 42 seconds Some Keyword ${arg} Configurable [Arguments] ${arg} ${timeout} [Timeout] ${timeout} Some Keyword ${arg} Run Keyword with Timeout [Arguments] ${keyword} @{args} &{kwargs} ${timeout}=1 minute [Documentation] Wrapper that runs another keyword with a configurable timeout. [Timeout] ${timeout} Run Keyword ${keyword} @{args} &{kwargs}用户关键词超时的特点:
- 超时在该用户关键词的执行期间生效;若整个关键词总耗时超过超时值,当前执行的关键词会被停止。
- 用户关键词超时在测试用例 teardown 期间同样适用,而测试超时不适用——这正是防止 teardown 挂起的机制。
- 当测试用例与其某个(或嵌套多个)关键词同时设置超时时,生效的是剩余时间最少的那一个。
历史兼容性说明:在早期 Robot Framework 版本中,可以为超时指定自定义错误消息;该功能在 Robot Framework 3.0.1 中被弃用,并在 3.2 中移除。因此不要依赖自定义超时错误消息。
2.3 超时的源码级实现原理
超时机制由 timeouts 包 实现。核心类_Timeout(Sortable)在初始化时记录超时字符串,通过timestr_to_secs将时间格式转换为秒数;start()在secs > 0时记录起始时间,time_left()计算剩余时间(粒度 1ms,源码注释说明该舍入用于规避 Windows 上threading.Event.wait()的偶发测试失败),timed_out()判断是否超时:
def timed_out(self): return self.active and self.time_left() <= 0_Timeout.run()在剩余时间不大于 0 时直接抛出TimeoutError,否则交由平台相关实现执行。TestTimeout与KeywordTimeout是_Timeout的两个子类(timeouts/init.py),分别对应测试超时与关键词超时——这就是"测试超时与关键词超时行为不同"(例如 teardown 期间是否生效、_sort_key决定同时存在时取剩余时间最少者)的底层来源。KeywordStore中search_order初始为空元组、timeouts集合由 context.py 的_add_timeout/_remove_timeout管理,_sort_key返回(not self.active, self.time_left()),确保多个超时并存时按剩余时间排序。
平台实现方面:
- POSIX 平台(posix.py):利用
signal.setitimer(ITIMER_REAL, ...)与signal(SIGALRM, ...)实现定时器,超时后抛出TimeoutError。 - Windows 平台(windows.py):使用线程机制实现等价行为。
- 若平台不支持(
nosupport.py),则退化为不可用实现。
在运行期,套件执行器(suiterunner.py)会为测试用例启动/关闭超时,test.timeout、result.timeout通过_add_timeout/_remove_timeout纳入执行上下文统一管理(context.py)。
三、关键词的并行执行(Parallel execution of keywords)
Robot Framework 的执行模型是单线程顺序执行的,因此当需要并行执行时,必须在测试库层面实现:让库在后台执行代码。典型模式是提供一对关键词:
- 启动类关键词:如
Start Something,启动后台执行并立即返回; - 取结果类关键词:如
Get Results From Something,阻塞等待结果就绪并返回。
官方文档以 Process 库的Start Process与Wait For Process作为范例(见 Process.py)。
Start Process(Process.py):在后台启动一个新进程并立即返回。它返回subprocess.Popen对象(Robot Framework 5.0 起直接返回 Popen;更早版本返回通用句柄,需用Get Process Object获取进程对象),可通过alias=命名,也可直接用返回对象操作(如${process.pid})。底层实现是subprocess.Popen(command, **conf.popen_config),并将进程注册为新的 active process。Wait For Process(Process.py):等待进程完成或到达超时。timeout支持 Robot Framework 时间格式,PythonNone、字符串NONE、0 或负数会被忽略;on_timeout可取continue(默认,进程保持运行)、terminate(优雅终止)、kill(强制停止)。进程在超时前结束、被终止或被 kill 时返回结果对象,进程仍在运行时返回None。
典型用法:
*** Test Cases *** Run Two Processes In Parallel ${p1} = Start Process python script1.py alias=first ${p2} = Start Process python script2.py alias=second # 后台并行运行,此处可穿插其他操作…… ${r1} = Wait For Process first ${r2} = Wait For Process second Should Be Equal As Integers ${r1.rc} 0 Should Be Equal As Integers ${r2.rc} 0需要指出的是,这并非测试用例级别的并行:测试用例仍按顺序执行,并行发生在单个测试用例内部、由库在后台管理多个进程/线程,这与 Robot Framework 的设计哲学一致——把并发细节封装在库中,测试数据保持简单可读。
四、小结
- 同名关键词:优先顺序为当前套件用户关键词 > 资源文件关键词 > 外部库关键词 > 标准库关键词;冲突时可用
LibraryName.Keyword全名精确指定,或用Set Library Search Order批量设定解析顺序(资源始终优先于库)。 - 超时:
Test Timeout/[Timeout]控制测试用例,[Timeout]控制用户关键词;时间格式支持秒数与描述性写法;多个超时并存时取剩余时间最少者;POSIX 用SIGALRM定时器实现。 - 并行:在库层面实现后台执行 + 取结果的成对关键词,
Process库的Start Process/Wait For Process是官方推荐范例。
如需深入了解,可继续阅读仓库中的相关文档与源码:
- 关联文档:AdvancedFeatures.rst
- 关键词解析实现:namespace.py
Set Library Search Order关键词文档与实现:BuiltIn.py- 超时实现:timeouts 包、posix.py、windows.py
- 并行执行范例:Process.py
- 时间格式规范:TimeFormat.rst
- 测试
- RPA
- 接口测试
【免费下载链接】robotframework
Generic automation framework for acceptance testing and RPA
相关推荐
Robot Framework命令行执行完全指南:标签过滤、执行顺序与超时控制
Robot Framework命令行执行完全指南:标签过滤、执行顺序与超时控制 Robot Framework(通用自动化测试框架)支持通过命令行直接启动测试,
测试RPA接口测试Robot Framework 5.1 alpha 2 新特性详解:本地化、标签体系重构与执行控制增强
Robot Framework 5.1 alpha 2 新特性详解:本地化、标签体系重构与执行控制增强 本文基于仓库内发布说明 doc/releasenotes
测试RPA接口测试Robot Framework 6.0 新特性全解析:本地化、参数转换与关键字命名空间深度指南
Robot Framework 6.0 新特性全解析:本地化、参数转换与关键字命名空间深度指南 Robot Framework 6.0 是该项目迈向本地化的首个
测试RPA接口测试
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考