声明:本文搬运自官方操作文档,仅用作学习,有错误的地方欢迎指正。
官方文档链接:RobotFramework--创建用户关键字
2.6 创建用户关键字
关键字表用于通过将现有关键字组合在一起创建新的更高级别的关键字。这些关键字称为用户关键字,以区别于测试库中实现的最低级别的库关键字。创建用户关键字的语法非常接近创建测试案例的语法,因此易于学习。
2.6.1 用户关键字语法
基本语法
在很多方面用户关键字与测试案例语法相同。用户关键字创建于关键字表中,这些关键字表仅根据用于识别它们的名称与测试案例表不同。第一列是用户关键字名称。此外,用户关键字也是从关键字创建的,来源于测试库中的关键字或其他用户关键字。第二列通常是关键字名称,但是如果设置了关键字返回值的变量,则位于后续列中。
大多数用户关键字需要参数(如上面的第二个示例)。本节的稍后部分会详细解释,类似于用户关键字返回值。
用户关键字可以在测试案例文件、资源文件和测试套件初始化文件中创建。资源文件中创建的关键字可用于使用它们的文件,而其他关键字仅在创建它们的文件中可用。
关键字表的设置
用户关键字可以具有与测试案例类似的设置,并且它们具有将它们与关键字名称分离的平方括号语法。下面列出了所有可用的设置,并在本节的稍后部分进行了解释。
[文档]
用于设置用户关键字文档。
[参数]
指定用户关键字参数。
[返回]
指定用户关键字返回值。
[拆解]
指定关键字拆解。Robot Framework2.6开始支持。
[超时]
设置可能的用户关键字超时。超时有专门部分讲述。
2.6.2 用户关键字名称和文档
用户关键字名称在用户关键字表的第一列中定义。名称应该是描述性的,并且如果关键字名称比较长也是可以接受的。实际上,在创建类似用例的测试案例时,最高级别的关键字通常被表述为句子甚至段落。
用户关键字可以设置为[Documentation]设置的文档,完全与测试案例文档一样。此设置在测试数据中记录用户关键字。它还显示在一个更正式的关键字文档中,Libdoc工具可以从资源文件创建该文档。最后,文档的第一行显示为测试日志中的关键字文档。
有时关键字需要删除、修改,或因其他原因而弃用。用户关键字可以通过以DEPRECATED
开头文档来标记弃用,这将在使用关键字时引起警告。更多信息请参阅弃用关键字部分。
2.6.3 用户关键字参数
大多数用户关键字使用参数。指定它们的语法可能是Robot Framework通常需要的最复杂的功能,但即使这样也相对容易。参数通常使用[Arguments] 设置进行指定,并且参数名称使用与变量相同的语法,例如${arg}
。
位置参数
指定参数的最简单方法(除了根本没有)仅使用位置参数。大多数案例都是使用这种方式。
语法是首先给出[Arguments] 设置,然后在随后的单元格中定义参数名称。每个参数都位于自身单元格中(与变量语法相同)。关键字必须使用已声明的所有参数。实际的参数名称对框架并不重要,但从用户的角度来看,它们应该尽可能描述清晰。变量名建议使用小写字母,如${my_arg}
, ${my arg}
或 ${myArg}
。
用户关键字获取不同数量的参数
默认值
位置参数在大多数情况下已经足够用了。但是,有时能需要用到这样的关键字,它需要很多参数且参数具有默认值。用户关键字就可以实现这种场景,而且并不会比基本语法复杂多少。简单来说,参数添加默认值首先有赋值符号(=),然后是值,例如${arg}=default
。参数可以有很多默认值,但必须定义在位置参数之后。
注意
默认值的语法对空格敏感。不允许在=符号之前进行空格,在它被视为默认值本身的一部分之后可能的空间。
当一个关键字接受几个具有默认值的参数,并且仅其中一些参数需要被覆盖时可以使用指定的参数语法。当此语法与用户关键字一起使用时,参数不需要使用${}
。例如,上面的第二个关键字可以像下面一样使用,并且${arg1}
仍将获取其默认值
最后必须注意的是,这种指定参数默认值的语法借鉴了Python函数默认值的语法。
参数变量
有时候即使使用了默认值也是不够的,还需要一个关键字来接受多个参数。用户关键字也能做到。这就需要将关键字的最后一个参数声明为列表变量(如@{varargs}
)。此语法可以与之前讲过的位置参数和默认值相结合,最后列表变量会获取与其他参数不匹配的所有剩余参数。因此列表变量的元素可以是任意数量,甚至是零。
用户关键字接受多个参数变量
请注意,如果上面的最后一个关键字用于多个参数,则第二个参数${opt}
始终获得给定值而不是默认值,即使给定值为空。最后一个例子还说明了用户关键字接受的参数变量@{others}
如何用于循环。这种高级的函数组合使用非常强大。
同样,Pythonistas 可能注意到,参数变量语法也非常接近 Python。
2.6.4 将参数嵌入关键字名称
Robot Framework还有另一种方法将参数传递给用户关键字,而不是在前一节中解释的关键字名称之后在单元中指定它们。此方法基于将参数直接嵌入关键字名称,其主要好处是使使用真实和清晰的句子作为关键字更加容易。
基本语法
这样使用关键字(如从列表中取狗和从列表中取猫)完全可以,但这些关键字必须单独执行。将参数嵌入关键字名称的想法是,您只需要一个关键字,Select ${animal} from list
使用嵌入式参数的关键字不能采取任何"正常"参数(用 [Arguments] 设置指定),但除此之外,它们的创建与其他用户关键字一样。名称中使用的参数自然可以在关键字内提供,它们具有不同的值,具体取决于关键字的调用方式。例如,如果要使用关键字Select dog from list
,则${animal}必须已经有了值dog
。显然,在关键字内并不是强制性使用所有参数,因此它们可以用作通配符。
这些关键字的使用方式也与其他关键字相同,只是其名称中不忽略空格和下划线,也跟其它关键字一样不区分大小写。例如,上面示例中的关键字可以写成select x from list
,但不能是Select x fromlist
.
嵌入式参数不支持默认值或像正常参数那样的可变参数数。调用关键字时可以使用变量,但会降低可读性。需要注意,嵌入式参数仅适用于用户关键字。
嵌入式参数匹配太多
使用嵌入式参数的一个棘手问题是确保调用关键字时使用的值与参数正确匹配。这是个问题,尤其是存在多个参数又有字符分离它们也可能出现在给定值中。例如,如果要匹配的城市太多,例如Select Los Angeles Lakers
, 则关键字Select ${city} ${team}
就不能正确执行。
解决这个问题的一个简单方法是引用参数(例如,Select "${city}" "${team}"
),并使用引用格式的关键字(例如*Select "Los Angeles" "Lakers"*
)。这种方法不足以解决所有问题,但它仍然受到强烈推荐,因为它使参数从关键字的其余部分脱颖而出。下一节将解释一个更强大但更复杂的解决方案,在定义变量时使用自定义正则表达式。最后,如果事情变得复杂,最好用回正常的位置参数。
参数溢出的问题经常发生,当创建关键字时会忽略given/when/then/and 前缀,经常会出现参数匹配过多的问题。例如*,${name} goes home
匹配Given Janne goes home
,使${name}
获得值Given Janne
。参数加引号,如"${name}" goes home
可以轻松解决这个问题。
使用自定义正则表达式
当执行使用嵌入式参数的关键字时,会使用正则表达式在内部匹配值(简称 regexps)。默认逻辑是名称中的每个参数都替换为.*?
去匹配任何字符串。这种逻辑工作相当正常,但正如上面刚才讨论的,有时关键字比预期更匹配。引用或以其他方式将参数与其他文本分开可能会有所帮助,但是下面的测试会失败,因为I execute "ls" with "-lh"
匹配两个定义的关键字。
这个问题的一个解决方案是使用自定义的正则表达式,确保关键字只匹配它应该在该特定上下文中的内容。要能够使用此功能,并充分理解本节中的示例,您至少需要了解正则表达语法的基本知识。
自定义嵌入式参数正则表达式在参数的底名后定义,将参数和表达式与冒号分开。例如,只匹配数字可定义为${arg:\d+}
。自定义正则表达式由下面的示例说明。
在上述示例中,关键字I execute "ls" with "-lh
,仅匹配I execute "${cmd}" with "${opts}"
。这是有保证的,因为自定义正则表达式[^"]+
*在I execute "${cmd:[^"]}"
意味着匹配的参数不能包含任何引号。在这种情况下,没有必要添加自定义表达式到其他I execute
变种。
提示
如果您引用参数,则使用正则表达[^"]+
保证参数仅匹配到第一个就结束匹配。
支持正则表达语法
Robot Framework依赖Python执行,自然使用 Python 的re模块,该模块有相当标准的正则表达语法。嵌入式参数完全支持此语法,但无法使用(?...)
扩展表达式。另请注意,匹配嵌入式参数不区分大小写。如果正则表达语法无效则创建关键字失败,在测试执行错误中会报错。
转义特殊字符
在自定义嵌入式参数表达式中使用时,需要转义一些特殊字符。首先,闭合的花括号(})需要用单个反斜杠(})转义,否则参数将结束。在上一个示例中用关键字*Today is ${date:\d{4\}-\d{2\}-\d{2\}}*
来说明过。
反斜杠(\)是 Python正则表达语法中的特殊字符, 因此,如果要使用字面上的反斜杠 需要转义。在这种情况下,最安全的转义序列是使用四个反斜杠(\\),但是,根据下一个字符,使用两个反斜杠就够了。
另请注意,使用正常的测试数据转义规则,不应转义关键字名称及嵌入式参数。例如,不应转义像${name:\w+}
等表达式
使用自定义嵌入式参数正则表达式的变量
每当使用自定义嵌入式参数正则表达式时,Robot Framework会优先匹配符合指定条件的文本。这表示完全可以使用嵌入式参数关键字的变量。如下实例:
使用自动匹配自定义正则表达式变量的缺点是,关键字获得的值可能实际上与指定的表达式不匹配。例如,上述示例中的变量${DATE}
可能包含任何值,而*Today is ${DATE}*
仍将匹配此关键字。
行为驱动的发展实例
将参数作为关键字名称的一部分的最大好处是,在以行为驱动的方式编写测试用例时,可以更轻松地使用高级句子式关键字。下面举例说明。注意前缀Given, When 和Then的关键字被排除。
RobotFramework中的嵌入式参数功能的灵感来自于如何在流行的 BDD 工具中创建步骤定义,称为Cucumber。
2.6.5 用户关键字返回值
与库关键字类似,用户关键字也可以有返回值。返回值与[Return]设置一起定义。这些值可以分配给测试案例或其他用户关键字中的变量。
在常规情况下,一个用户关键字返回一个值,它可以设置为标量。这是通过在[Return]设置后在下一个单元格中具有返回值来完成的。用户关键字也可以返回多个值,然后这些值可以同时分配到多个标量,分配到列表变量或同时分给标量和列表变量。只需在[Return]设置后在不同的单元中指定这些值,即可返回多个值。
2.6.6 关键字拆解
从Robot Framework 2.6 开始,用户关键字也可以被拆毁。它是使用[Teardown]**设置定义的。
关键字拆解方式与测试案例拆解大致相同。最点是,拆解始终是一个关键字,尽管它可以是另一个用户关键字,并且当用户关键字失败时也会被执行。此外,即使其中一个步骤失败,所有步骤也会执行。但是,如果关键字拆解失败则测试案例执行失败,并且测试中的后续步骤无法运行。拆解执行的关键字名称也可以是变量。