2.6创建用户关键字
关键字表用于通过将现有关键字组合在一起来创建新的更高级别关键字。这些关键字称为用户关键字,以区别于 测试库中实现的最低级库关键字。创建用户关键字的语法与创建测试用例的语法非常接近,这使其易于学习。
2.6.1用户关键字语法
基本语法
在许多方面,整体用户关键字语法与测试用例语法相同 。用户关键字在关键字表中创建,这些关键字表与测试用例表的区别仅在于用于标识它们的名称。用户关键字名称与测试用例名称类似,位于第一列。用户关键字也是从关键字创建的,可以是测试库中的关键字或其他用户关键字。关键字名称通常位于第二列,但是在从关键字返回值设置变量时,它们位于后续列中。
用户关键字示例
关键词 | 行动 | 争论 | 争论 |
---|---|---|---|
Open Login Page | Open Browser | http://host/login.html | |
Title Should Be | Login Page | ||
Title Should Start With | [Arguments] | ${expected} | |
${title} = | Get Title | ||
Should Start With | ${title} | ${expected} |
大多数用户关键字都需要参考。此重要功能已在上面的第二个示例中使用,本节后面将详细 介绍,与用户关键字返回值类似。
可以在测试用例文件,资源文件和测试套件初始化文件中创建用户关键字。在资源文件中创建的关键字可用于使用它们的文件,而其他关键字仅在创建它们的文件中可用。
关键字表格中的设置
用户关键字可以具有与测试用例类似的设置,并且它们具有相同的方括号语法,将它们与关键字名称分开。下面列出了所有可用的设置,本节稍后将对其进行说明。
- [文档]
- 用于设置用户关键字文档。
- [参数]
- 指定用户关键字参数。
- [返回]
- 指定用户关键字返回值。
- [拆除]
- 指定关键字拆解。从Robot Framework 2.6开始提供。
- [超时]
- 设置可能的用户关键字超时。超时在他们自己的一节中讨论。
2.6.2用户关键字名称和文档
用户关键字名称在user关键字表的第一列中定义。当然,名称应该是描述性的,并且可以使用相当长的关键字名称。实际上,在创建类似用例的测试用例时,最高级别的关键字通常被表述为句子甚至段落。
用户关键字可以包含使用 [Documentation]设置设置的文档,与测试用例文档完全相同。此设置记录测试数据中的用户关键字。它还显示在更正式的关键字文档中,libdoc工具可以从资源文件创建。最后,文档的第一行显示为测试日志中的关键字文档 。
有时需要删除关键字,替换为新关键字,或者出于其他原因弃用关键字。通过使用* DEPRECATED *启动文档,可以将用户关键字标记为已弃用,这将在使用keyoword时引发警告。有关更多信息,请参阅 弃用关键字部分。
2.6.3用户关键字参数
大多数用户关键字需要采用一些参数。指定它们的语法可能是Robot Framework通常需要的最复杂的功能,但即使这样也相对容易,特别是在大多数常见情况下。参数通常使用[Arguments]设置指定,参数名称使用与变量相同的语法,例如$ {arg}。
位置参数
指定参数的最简单方法(除了根本没有它们)只使用位置参数。在大多数情况下,这就是所需要的。
语法是这样的,首先给出[Arguments]设置,然后在后续单元格中定义参数名称。每个参数都在自己的单元格中,使用与变量相同的语法。关键字必须与其签名中的参数名称一样多的参数使用。实际的参数名称与框架无关,但从用户的角度来看,它们应该尽可能具有描述性。建议在变量名中使用小写字母,可以是 $ {my_arg},$ {my arg}或$ {myArg}。
用户关键字采用不同数量的参数
Keyword | Action | Argument | Argument | Argument |
---|---|---|---|---|
One Argument | [Arguments] | ${arg_name} | ||
Log | Got argument ${arg_name} | |||
Three Arguments | [Arguments] | ${arg1} | ${arg2} | ${arg3} |
Log | 1st argument: ${arg1} | |||
Log | 2nd argument: ${arg2} | |||
Log | 3rd argument: ${arg3} |
默认值
在大多数情况下,位置参数可能已足够。但是,有时能够使用不同数量的参数的关键字并且具有未给定的参数的默认值是有用的。用户关键字也允许这样做,并且所需的新语法不会对已经讨论过的基本语法增加太多。简而言之,默认值被添加到参数中,因此首先存在等号(=)然后是值,例如$ {arg} = default。默认值可以有很多参数,但它们都必须在正常的位置参数之后给出。
注意
默认值的语法是空间敏感的。在=符号之前的空格是不允许的,并且在它之后的可能空格被认为是默认值本身的一部分。
Keyword | Action | Argument | Argument |
---|---|---|---|
One Argument With Default Value | [Arguments] | ${arg}=default value | |
[Documentation] | This keyword takes | 0-1 arguments | |
Log | Got argument ${arg} | ||
Two Arguments With Defaults | [Arguments] | ${arg1}=default 1 | ${arg2}=default 2 |
[Documentation] | This keyword takes | 0-2 arguments | |
Log | 1st argument ${arg1} | ||
Log | 2nd argument ${arg2} | ||
One Required And One With Default | [Arguments] | ${required} | ${optional}=default |
[Documentation] | This keyword takes | 1-2 arguments | |
Log | Required: ${required} | ||
Log | Optional: ${optional} |
当关键字接受具有默认值的多个参数并且只需要覆盖其中一些参数时,使用命名参数语法通常很方便 。当此语法与用户关键字一起使用时,将指定参数而不使用$ {} 修饰。例如,上面的第二个关键字可以像下面一样使用,$ {arg1}仍会获得其默认值。
Test Case | Action | Argument | Argument |
---|---|---|---|
Example | Two Arguments With Defaults | arg2=new value |
正如所有Pythonistas必须已经注意到的那样,指定默认参数的语法很大程度上受到函数默认值的Python语法的启发。
可变数量的参数
有时甚至默认值都不够,并且需要一个接受任意数量参数的关键字。用户关键字也支持此功能。所需要的只是将列表变量( 例如@ {varargs})作为关键字签名中的最后一个参数。此语法可以与先前描述的位置参数和默认值组合,最后,list变量获取与其他参数不匹配的所有剩余参数。因此列表变量可以具有任意数量的项目,甚至为零。
Keyword | Action | Argument | Argument | Argument |
---|---|---|---|---|
Any Number Of Arguments | [Arguments] | @{varargs} | ||
Log Many | @{varargs} | |||
One Or More Arguments | [Arguments] | ${required} | @{rest} | |
Log Many | ${required} | @{rest} | ||
Required, Default, Varargs | [Arguments] | ${req} | ${opt}=42 | @{others} |
Log | Required: ${req} | |||
Log | Optional: ${opt} | |||
Log | Others: | |||
: FOR | ${item} | IN | @{others} | |
Log | ${item} |
同样,Pythonistas可能会注意到可变数量的参数语法非常接近Python中的参数。
请注意,如果上面的最后一个关键字与多个参数一起使用,则第二个参数$ {opt}始终获取给定值而不是默认值。即使给定值为空,也会发生这种情况。最后一个示例还说明了如何在for循环中使用user关键字接受的可变数量的参数。这两个相当高级的功能的组合有时可能非常有用。
2.6.4将参数嵌入到关键字名称中
Robot Framework还有另一种方法可以将参数传递给用户关键字,而不是在关键字名称后面的单元格中指定它们,如上一节中所述。此方法基于将参数直接嵌入到关键字名称中,其主要好处是可以更轻松地将真实和清晰的句子用作关键字。
基本语法
始终可以使用“ 从列表中选择狗”和“ 从列表中选择猫”等关键字,但所有这些关键字必须单独实施。将参数嵌入到关键字名称中的想法是,您只需要一个名称为Select $ {animal} from list的关键字 。
Keyword | Action | Argument | Argument |
---|---|---|---|
Select ${animal} from list | Open Page | Pet Selection | |
Select Item From List | animal_list | ${animal} |
使用嵌入式参数的关键字不能采用任何“普通”参数(使用[Arguments]设置指定),否则它们就像其他用户关键字一样创建。名称中使用的参数自然可以在关键字中使用,它们具有不同的值,具体取决于关键字的调用方式。例如, 如果使用关键字中的选择狗,则前一个$ {animal}具有值dog。显然,在关键字中使用所有这些参数并不是必须的,因此它们可以用作通配符。
除了在名称中不忽略空格和下划线之外,这些关键字的使用方式与其他关键字的使用方式相同。但是,它们与其他关键字一样不区分大小写。例如,上面示例中的关键字可以像列表中的选择x一样使用 ,但不能像选择x fromlist那样使用。
嵌入式参数不支持默认值或可变数量的参数,如普通参数。在调用这些关键字时使用变量是可能的,但这会降低可读性。另请注意,嵌入式参数仅适用于用户关键字。
嵌入式参数匹配太多
使用嵌入式参数的一个棘手的部分是确保调用关键字时使用的值与正确的参数匹配。这是一个问题,特别是如果有多个参数并且分隔它们的字符也可能出现在给定值中。例如,如果与包含Select Los Angeles Lakers等部分的城市一起使用,则关键字Select $ {city} $ {team}无效。
解决这个问题的一个简单方法是引用参数(例如 选择“$ {city}”“$ {team}”)并使用引用格式的关键字(例如选择“洛杉矶”“湖人队”)。但是,这种方法还不足以解决所有这类冲突,但仍然强烈推荐这种方法,因为它使得参数从关键字的其余部分中脱颖而出。更强大但也更复杂的解决方案,在定义变量时使用自定义正则表达式,将在下一节中介绍。最后,如果事情变得复杂,那么使用普通的位置参数可能更好。
在创建忽略给定/ when / then /和前缀的关键字时,通常会发生参数匹配过多的问题。例如, $ {name}回家比赛鉴于Janne回家,因此$ {name}获得价值给予Janne。围绕参数的引用,如“$ {name}”回家,很容易解决这个问题。
使用自定义正则表达式
当调用具有嵌入参数的关键字时,使用正则表达式 (简称regexps)在内部匹配值。默认逻辑使得名称中的每个参数都替换为模式。*?基本上匹配任何字符串。这个逻辑工作得相当好正常,但上面刚刚讨论,有时关键词匹配超过预期。引用或以其他方式将参数与其他文本分开可能有所帮助,但是,例如,下面的测试失败,因为关键字 I执行带有“-lh”的“ls”匹配两个定义的关键字。
Test Case | Step |
---|---|
Example | I execute "ls" |
I execute "ls" with "-lh" |
Keyword | Action | Argument | Argument |
---|---|---|---|
I execute "${cmd}" | Run | ${cmd} | |
I execute "${cmd}" with "${opts}" | Run | ${cmd} ${opts} | |
此问题的解决方案是使用自定义正则表达式,该表达式确保关键字仅匹配特定上下文中的内容。为了能够使用此功能,并完全理解本节中的示例,您至少需要了解正则表达式语法的基础知识。
在参数的基本名称之后定义自定义嵌入式参数正则表达式,以便使用冒号分隔参数和正则表达式。例如,只能匹配数字的参数可以定义为$ {arg: d +}。以下示例说明了使用自定义正则表达式。
Test Case | Step |
---|---|
Example | I execute "ls" |
I execute "ls" with "-lh" | |
I type 1 + 2 | |
I type 53 - 11 | |
Today is 2011-06-27 |
Keyword | Action | Argument | Argument | Argument |
---|---|---|---|---|
I execute "${cmd:[^"]+}" | Run | ${cmd} | ||
I execute "${cmd}" with "${opts}" | Run | ${cmd} ${opts} | ||
I type ${a:d+} ${operator:[+-]} ${b:d+} | Calculate | ${a} | ${operator} | ${b} |
Today is ${date:d{4}-d{2}-d{2}} | Log | ${date} | |
在上面的示例关键字中,我执行“ls”与“-lh”匹配,我只用“$ {opts}”执行“$ {cmd}”。这是保证,因为自定义正则表达式[^“] +在我执行‘$ {CMD:[^’]}”指的是匹配的参数不能包含任何报价。在这种情况下,不需要将自定义regexp添加到另一个I执行变体中。
小费
如果引用参数,则使用正则表达式[^“] + 保证参数仅匹配第一个结束引号。
支持正则表达式语法
使用Python实现,Robot Framework自然使用Python的 re模块,该模块具有非常标准的正则表达式语法。嵌入式参数完全支持此语法,但不能使用格式(?...)的 regexp扩展。另请注意,匹配嵌入式参数不区分大小写。如果正则表达式语法无效,则创建关键字失败,并在测试执行错误中显示错误。
逃避特殊字符
在自定义嵌入式参数regexp中使用时,需要转义一些特殊字符。首先,模式中可能关闭花括号(})需要使用单个反斜杠(})进行转义,否则参数将在那里结束。前面的示例中说明了关闭魁梧的大括号,其中关键字今天是$ {date: d {4 } - d {2 } - d {2 }}。
反斜杠()是Python正则表达式语法中的特殊字符,因此如果要使用文字反斜杠字符,则需要进行转义。在这种情况下最安全的转义序列是四个反斜杠(\\)但是,根据下一个字符,两个反斜杠也可能就足够了。
公告同时在他们的关键字名称和可能的嵌入参数应该不使用正常进行转义测试数据转义规则。这意味着,例如,$ {name: w +}等表达式中的反斜杠不应该被转义。
使用自定义嵌入式参数正则表达式的变量
每当使用自定义嵌入式参数正则表达式时,Robot Framework会自动增强指定的正则表达式,以便除了与模式匹配的文本外,它们还匹配变量。这意味着始终可以使用具有嵌入参数的关键字的变量。例如,以下测试用例将使用前面示例中的关键字传递。
使用自定义正则表达式的变量
Variable | Value |
---|---|
${DATE} | 2011-06-27 |
Test Case | Step |
---|---|
Example | I type ${1} + ${2} |
Today is ${DATE} |
变量自动匹配自定义正则表达式的缺点是,关键字获取的值可能实际上与指定的正则表达式不匹配。例如,上例中的变量 $ {DATE}可以包含任何值,而 今天$ {DATE}仍然匹配相同的关键字。
行为驱动的开发示例
将参数作为关键字名称的一部分的最大好处是,在以行为驱动的方式编写测试用例时,可以更容易地使用更高级别的类似句子的关键字。以下示例说明了这一点。还要注意的是前缀考虑,当且然后被冷落的关键词定义的。
BDD样式测试使用的嵌入式参数
Test Case | Step |
---|---|
Add two numbers | Given I have Calculator open |
When I add 2 and 40 | |
Then result should be 42 | |
Add negative numbers | Given I have Calculator open |
When I add 1 and -2 | |
Then result should be -1 |
Keyword | Action | Argument | Argument |
---|---|---|---|
I have ${program} open | Start Program | ${program} | |
I add ${number 1} and ${number 2} | Input Number | ${number 1} | |
Push Button | + | ||
Input Number | ${number 2} | ||
Push Button | = | ||
Result should be ${expected} | ${result} = | Get Result | |
Should Be Equal | ${result} | ${expected} |
注意
Robot Framework中的嵌入式参数功能受到如何在名为Cucumber的流行BDD工具中创建步骤定义的启发。
2.6.5用户关键字返回值
与库关键字类似,用户关键字也可以返回值。返回值使用[Return] 设置定义。然后可以将值分配给测试用例或其他用户关键字中的变量。
在典型情况下,user关键字返回一个值,并且可以将其设置为标量变量。这是通过在[Return]设置之后的下一个单元格中返回值来完成的。用户关键字也可以返回多个值,然后可以将它们一次分配到多个标量变量,列表变量,或标量变量和列表变量。只需在[Return]设置后指定不同单元格中的值,即可返回多个值 。
用户关键字返回值
Test Case | Action | Argument | Argument | Argument |
---|---|---|---|---|
One Return Value | ${ret} = | Return One Value | argument | |
Some Keyword | ${ret} | |||
Multiple Values | ${a} | ${b} | ${c} = | Return Three Values |
@{list} = | Return Three Values | |||
${scalar} | @{rest} = | Return Three Values |
Keyword | Action | Argument | Argument | Argument |
---|---|---|---|---|
Return One Value | [Arguments] | ${arg} | ||
Do Something | ${arg} | |||
${value} = | Get Some Value | |||
[Return] | ${value} | |||
Return Three Values | [Return] | foo | bar | zap |
2.6.6关键字拆解
从Robot Framework 2.6开始,用户关键字也可能被拆除。它是使用[Teardown]设置定义的。
关键字拆解与测试案例拆解的工作方式大致相同。最重要的是,拆卸始终是一个关键字,尽管它可以是另一个用户关键字,并且当用户关键字失败时也会执行。此外,即使其中一个失败,也会执行拆解的所有步骤。但是,关键字拆解失败将导致测试用例失败,并且不会运行测试中的后续步骤。要作为拆卸执行的关键字的名称也可以是变量。
User Keyword | Action | Argument | Argument |
---|---|---|---|
With Teardown | Do Something | ||
[Teardown] | Log | keyword teardown | |
Using variables | [Documentation] | Teardown given as | variable |
Do Something | |||
[Teardown] | ${TEARDOWN} |