声明:本文搬运自官方操作文档,仅用作学习,有错误的地方欢迎指正。
原文链接:RobotFramework--变量
2.5 变量
2.5.1 简介
变量是Robot Framework的一个不可或缺的特性,它们可以在测试数据的大多数地方使用。最常见的是,它们用于测试用例表和关键字表中关键字的参数,但所有设置都允许在其值中使用变量。无法使用变量指定普通关键字名称,但可以使用BuiltIn关键字 Run Keyword
获得相同的效果。
Robot Framework本身有两种变量,scalars和lists,它们分别具有$ {SCALAR}
和@ {LIST}
的语法。除此之外,环境变量可以直接与语法%{VARIABLE}
一起使用。
在以下情况下建议使用变量:
当字符串经常在测试数据中更改时。使用变量,您只需在一个地方进行这些更改。
创建独立于系统和操作系统的测试数据时。使用变量而不是硬编码字符串可以大大减轻。因为在启动测试时可以从命令行设置变量,所以更改系统特定的变量很容易。这也有助于本地化测试,这通常涉及使用不同的字符串运行相同的测试。
当需要将字符串以外的对象作为关键字的参数时。
当不同的关键字,甚至在不同的测试库中,需要进行通信。您可以将一个关键字的返回值分配给变量,并将其作为参数提供给另一个变量。
当测试数据中的值很长或者复杂时。例如,
$ {URL}
比http://long.domain.name:8080/path/to/service?foo=1&bar=2&zap=42
短 。
如果在测试数据中使用了不存在的变量,则使用它的关键字将失败。如果需要使用与变量相同的语法作为文字字符串,则必须使用反斜杠对其进行转义,如\ $ {NAME}。
2.5.2变量类型
Robot Framework的变量与关键字类似,不区分大小写、忽略空格和下划线。但是,全局变量建议使用大写字母(例如,${PATH}
或$ {TWO_WORDS}
),仅在某些测试用例或用户关键字中的变量使用小写字母(例如:$ {my_var}
或 $ {myVar}
)。但更重要的是,应该始终如一地使用案例。
与使用类似变量语法的一些编程语言不同,花括号({ and }
)在Robot Framework测试数据中是必需的。基本上变量名称可以在花括号之间包含任何字符。但是,建议仅使用a到z的字母字符,数字,下划线和空格,甚至是使用扩展变量语法的要求。
标量变量
在测试数据中使用标量变量时,它们将替换为分配给它们的值。虽然标量变量最常用于简单字符串,但您可以为它们分配任何对象,包括列表。标量变量语法(例如 ${NAME}
)应该为大多数用户所熟悉,因为它也用于shell脚本和Perl编程语言。
下面的例子说明了标量变量的用法。假设变量$ {GREET}
和$ {NAME}
可用并分别分配给字符串Hello
和world
,两个示例测试用例都是等效的。
当标量变量用作测试数据单元格中的唯一值时,标量变量将替换为它具有的值。值可以是任何对象。当标量变量在测试数据单元格中使用其他任何内容(常量字符串或其他变量)时,其值首先转换为Unicode字符串,然后连接到该单元格中的任何内容。将值转换为字符串意味着调用对象的方法__unicode __
(在Python中,str作为后备)或toString
(在Java中)。
下面的示例演示了单独使用单元格中的变量或其他内容之间的区别。首先,让我们假设我们将变量$ {STR}
设置为字符串Hello,world!
和$ {OBJ}
设置为以下Java对象的实例:
public class MyObj {
public String toString() {
return "Hi, tellus!";
}
}
设置这两个变量后,我们将得到以下测试数据:
最后,当执行此测试数据时,不同的关键字会收到如下所述的参数:
- KW 1得到一个字符串
Hello,world!
- KW 2得到一个存储变量$ {OBJ}的对象
- KW 3得到一个字符串
I said "Hello, world!"
- KW 4得到了一个字符串
You said "Hi, tellus!"
List变量
List变量是可以为其分配多个值的复合变量。简而言之,它们总是列表,并且可以包含无限数量的条目(也可以是空列表)。列表变量的主要好处是它们允许您为更大的数据集指定名称。虽然列表变量通常只包含字符串,但其他内容也是可能的。
在测试数据中使用列表变量时,列表的元素将作为新单元格插入测试数据中。因此,如果列表变量包含两个元素,则包含列表变量的单元格将变为具有列表变量内容的两个单元格。请注意,包含列表变量的单元格不应包含其他内容。列表变量语法@ {NAME}
是从Perl借来的。
假设列表变量@ {USER}
设置为值 ['robot','secret']
,则以下两个测试用例是等效的。
访问单个列表变量项
也可以使用语法@ {NAME} [i]
从列表变量访问某个值,其中i是所选值的索引。索引从零开始,并且尝试访问索引太大的值会导致错误。以这种方式访问的列表项可以与标量变量类似地使用:
使用列表变量作为标量变量
只需将@替换为$,就可以使用列表变量作为包含列表的标量变量。这使得可以将列表变量与列表相关的关键字一起使用,例如,来自BuiltIn
和Collections
库。仅当没有与列表变量具有相同基本名称的标量变量时,此功能才有效。在这些情况下,标量变量具有优先权,而使用其值。
使用列表变量和设置
列表变量只能用于某些设置。它们可以用于导入库和变量文件的参数,但库和变量文件名本身不能是列表变量。另外,使用setups
和teardowns list
变量不能用作关键字的名称,但可以在参数中使用。使用标签相关设置,可以自由使用。在不支持列表变量的位置可以使用标量变量。
环境变量
Robot Framework允许使用语法%{ENV_VAR_NAME}
在测试数据中使用环境变量。它们仅限于字符串值。
在测试执行之前在操作系统中设置的环境变量在它期间可用,并且可以使用关键字Set Environment Variable
创建新变量,或者使用关键字Delete Environment Variable
删除现有变量,这两个变量都在OperatingSystem
库中可用 。由于环境变量是全局变量,因此在一个测试用例中设置的环境变量可以用在其后执行的其他测试用例中。但是,在测试执行后,对环境变量的更改无效。
Java系统属性
使用Jython运行测试时,可以 使用与环境变量相同的语法来访问Java系统属性。如果存在环境变量和具有相同名称的系统属性,则将使用环境变量。Robot Framework 2.6中添加了对访问Java系统属性的支持。
2.5.3创建变量
变量可以从不同的来源开始存在,如下面的小节所述。
变量表
变量的最常见来源是测试用例文件和资源文件中的变量表。变量表很方便,因为它们允许在与其他测试数据相同的位置创建变量,并且所需的语法非常简单。它们的主要缺点是它们只能将变量分配到字符串或字符串列表中。如果需要其他值类型,可变文件可能是更好的选择。
创建标量变量
最简单的变量赋值是将字符串设置为标量变量。这是通过在Variable表的第一列中给出变量名(包括 $ {}
)和在第二列中给出值来完成的。如果第二列为空,则将空字符串设置为值。此外,可以在值中使用已定义的变量。
在变量名之后使用=使得赋值变量更明确,但不强制。
创建列表变量
创建列表变量就像创建标量变量一样简单。同样,变量名称位于Variable表的第一列中,值位于后续列中。列表变量可以具有任意数量的值,从零开始,如果需要许多值,则可以将它们拆分为多行。
变量文件
变量文件是创建不同类型变量的最强大机制。可以使用它们将变量分配给任何对象,并且它们还可以动态创建变量。在资源和变量文件一节中解释了变量文件语法和使用变量文件。
在命令行中设置变量
可以使用--variable(-v)
选项从命令行单独设置变量,也可以使用带有--variablefile(-V)
选项的变量文件设置变量 。从命令行设置的变量全局可用于所有已执行的测试数据文件,并且它们还会覆盖变量表和测试数据中导入的变量文件中具有相同名称的可能变量。
设置单个变量的语法是--variable name:value
,其中名称是变量的名称,而不 $ {}
和价值是它的价值。可以多次使用此选项设置多个变量。只能使用此语法设置标量变量,它们只能获取字符串值。许多特殊字符很难在命令行中表示,但可以使用--escape
选项进行转义。
--variable EXAMPLE:value
--variable HOST:localhost:7272 --variable USER:robot
--variable ESCAPED:Qquotes_and_spacesQ --escape quot:Q --escape space:_
在上面的示例中,设置变量以便
-
$ {EXAMPLE}
获取value
-
$ {HOST}
和$ {USER}
获取localhost:7272
和robot
-
$ {ESCAPED}
获取值“quotes and spaces”
从命令行获取变量文件的基本语法是--variablefile path/to/variables.py
,并且将可变文件转换为使用部分有更多细节。实际创建的变量取决于引用的变量文件中的变量。
如果从命令行给出变量文件和单个变量,则后者具有更高的优先级。
从关键字返回值
关键字的返回值也可以设置为变量。这允许甚至在不同的测试库中不同关键字之间的通信。以下示例说明了简单案例的语法:
在上面的示例中,Get X
关键字返回的值首先设置为变量$ {x}
,然后由Log
关键字使用。此语法适用于关键字返回某些内容的所有情况,并且该变量设置为关键字返回的任何值。在变量名之后使用等号=不是强制性的,但建议使用,因为它使赋值更明确。
如果关键字返回列表,则还可以将返回值分配给多个标量变量和/或一个列表变量。从Robot Framework 2.5开始,这适用于所有类似列表的对象,但在此之前,只支持Python列表,元组和Java数组。
假设关键字Get 3返回列表 [1,2,3],则创建以下变量:
-
${scalar}
with the value[1, 2, 3]
-
${a}
,${b}
and${c}
with the values1
,2
, and3
-
${first}
with the value1
, and@{rest}
with the value[2, 3]
-
@{list}
with the value[1, 2, 3]
以这种方式设置的变量在其他方面与任何其他变量类似,但它们仅在测试用例或创建它们的关键字的范围内可用。因此,例如,不可能在一个测试用例中设置变量并在另一个测试用例中使用它。这是因为,通常,自动化测试用例不应相互依赖,并且意外设置在别处使用的变量可能会导致难以调试的错误。如果确实需要在一个测试用例中设置变量并在另一个测试用例中使用它,则可以使用内置关键字,如下一节所述。
使用内置的Set Test/Suite/Global Variable关键字
Builtin库具有一些关键字设置测试变量, 设置suite变量和设置全局变量可用于测试执行过程中动态地设置变量。如果变量已存在于新范围内,则其值将被覆盖,否则将创建新变量。
使用Set Suite Variable关键字设置的变量在当前执行的测试套件的范围内随处可用。因此,使用此关键字设置变量与使用测试数据文件中的变量表创建变量或从变量文件导入变量具有相同的效果。其他测试套件(包括可能的子测试套件)不会看到使用此关键字设置的变量。
使用Set Global Variable关键字设置的变量在设置后执行的所有测试用例和套件中全局可用。因此,使用此关键字设置变量与使用选项--variable
或--variablefile
从命令行创建具有相同的效果 。由于此关键字可以在任何地方更改变量,因此应谨慎使用。
2.5.4内置变量
Robot Framework提供了一些可自动使用的内置变量。
操作系统变量
与操作系统相关的内置变量使测试数据与操作系统无关。
数字变量
变量语法可用于创建整数和浮点数,如下例所示。当关键字期望获得实际数字而不是看起来像数字的字符串作为参数时,这非常有用。
从Robot Framework 2.6开始,也可以分别使用0b,0o 和0x前缀从二进制,八进制和十六进制值创建整数。语法是区分大小写的。
布尔值和None/null变量
此外,布尔值和Python None
和Java null
可以使用与数字类似的变量语法创建。
这些变量不区分大小写,例如$ {True}
和$ {true}
是等效的。此外,$ {None}
和$ {null}
是同义词,因为在Jython解释器上运行测试时,Jython会在必要时自动将None和 null转换为正确的格式。
空格和Empty变量
可以分别使用变量${SPACE}
和{EMPTY}
创建空格和空字符串 。例如,当需要时,这些变量是有用的使用反斜杠转义空格或空单元格时。如果需要多个空格,则可以使用扩展变量语法,如 $ {SPACE * 5}。在下面的示例中,Should Be Equal
关键字获取相同的参数,但使用变量的参数比使用反斜杠的参数更容易理解。
自动变量
一些自动变量也可用于测试数据。这些变量在测试执行期间可以具有不同的值,并且其中一些变量甚至不可用。
2.5.5变量优先级和范围
来自不同来源的变量具有不同的优先级,并且可以在不同的范围内使用。
变量优先级
命令行中的变量
在命令行中设置的变量具有在实际测试执行开始之前可以设置的所有变量的最高优先级。它们覆盖在测试用例文件中的变量表中以及在测试数据中导入的资源和变量文件中创建的可能变量。
单独设置变量(--variable option
)会覆盖使用变量文件设置的变量(--variablefile
选项)。如果多次指定相同的单个变量,则最后指定的变量将覆盖之前的变量。这允许在启动脚本中设置变量的默认值,并从命令行覆盖它们。但请注意,如果多个变量文件具有相同的变量,则首先指定的文件中的变量具有最高优先级。
测试用例文件中的变量表
使用测试用例文件中的Variable表创建的变量可用于该文件中的所有测试用例。这些变量会覆盖导入的资源和变量文件中具有相同名称的可能变量。
在变量表中创建的变量在创建它们的文件中的所有其他表中都可用。这意味着它们也可以在Setting表中使用,例如,用于从资源和变量文件导入更多变量。
导入的资源和变量文件
从资源和变量文件导入的变量具有在测试数据中创建的所有变量的最低优先级。资源文件和变量文件中的变量具有相同的优先级。如果多个资源和/或变量文件具有相同的变量,则首先导入的文件中的变量将被使用。
如果资源文件导入资源文件或变量文件,则其自己的Variable表中的变量具有比它导入的变量更高的优先级。所有这些变量都可用于导入此资源文件的文件。
请注意,从资源和变量文件导入的变量在导入它们的文件的变量表中不可用。这是因为在导入资源文件和变量文件的设置表之前处理变量表。
在测试执行期间设置的变量
在测试执行期间使用关键字或内置 关键字的返回值设置的变量Set Test / Suite / Global Variable始终覆盖设置范围内的可能现有变量。从某种意义上说,它们具有最高优先级,但另一方面它们不会影响它们所定义范围之外的变量。
内置变量
内置变量(如
${TEMPDIR
和{TEST_NAME}
) 具有所有变量的最高优先级。它们不能使用Variable表或命令行覆盖,但即使它们也可以在测试执行期间重置。此规则的一个例外是数字变量,如果没有找到变量,则动态解析。因此可以覆盖它们,但这通常是一个坏主意。另外$ {CURDIR} 是特殊的,因为它在测试数据处理期间已被替换。
变量作用范围
根据创建的位置和方式,变量可以具有全局,测试套件,测试用例或用户关键字范围。
全局变量
全局变量在测试数据中随处可用。这些变量通常使用
--variable
和--variablefile
选项从命令行设置,但也可以使用BuiltIn关键字Set Global Variable
在测试数据中的任何位置创建新的全局变量或更改现有变量。此外,内置变量也是全局变量。
建议对所有全局变量使用大写字母。
测试套件范围
具有测试套件范围的变量可在测试套件中的任何位置使用,可在其中定义或导入。它们可以在变量表中创建,从资源和变量文件导入,或者在测试执行期间使用BuiltIn关键字 Set Suite Variable进行设置。
测试套件范围不是递归的,这意味着更高级别测试套件中的可用变量在低级套件中不可用。如有必要,可以使用资源和变量文件来共享变量。
由于这些变量可以在使用它们的测试套件中被视为全局变量,因此建议使用大写字母。
测试用例范围
在测试用例中根据关键字的返回值创建的变量具有测试用例范围,并且仅在该测试用例中可用。创建它们的另一种可能性是在该特定测试用例中的任何位置使用BuiltIn关键字 Set Test Variable。测试用例变量是本地的,应该使用小写字母。
用户关键字范围
用户关键字从传递给它们的参数中获取自己的变量, 并从它们使用的关键字返回值。这些变量也是本地的,应该使用小写字母。
2.5.6高级变量功能
扩展变量语法
扩展变量语法可以与设置为标量变量的对象一起使用。它允许访问对象的属性(例如, $ {obj.name}
或$ {obj.some_attr}
),甚至可以调用其方法(例如,$ {obj.get_name()}
或 $ {obj.getSomething ('arg')}
)。
扩展变量语法是一个强大的功能,但应谨慎使用。相反,访问属性通常不是问题,因为具有多个属性的对象的一个变量通常比具有多个变量更好。另一方面,调用方法,特别是当它们与参数一起使用时,可能会使测试数据变得复杂。如果发生这种情况,建议将代码移动到测试库中。
扩展变量语法的最常见用法在下面的示例中说明。首先假设我们有以下变量文件 和测试用例:
class MyObject:
def __init__(self, name):
self.name = name
def eat(self, what):
return '%s eats %s' % (self.name, what)
def __str__(self):
return self.name
OBJECT = MyObject('Robot')
DICTIONARY = { 1: 'one', 2: 'two', 3: 'three'}
执行此测试数据时,关键字将获取参数,如下所述:
- KW 1 gets string
Robot
- KW 2 gets string
Robot eats Cucumber
- KW 3 gets string
two
扩展变量语法按以下顺序计算:
使用完整变量名称搜索变量。仅在未找到匹配变量时才评估扩展变量语法。
创建基本变量的真实名称。名称的主体包括$
之后的所有字符直到第一次出现非字母数字字符或空格,例如OBJECT
IN${OBJECT.name}
和DICTIONARY
IN${DICTIONARY [2]}
。
搜索与主体匹配的变量。如果没有匹配项,则引发异常并且测试用例失败。
大括号内的表达式被计算为Python表达式,因此基本变量名称将替换为其值。如果由于语法无效而导致评估失败或查询的属性不存在,则会引发异常并且测试 失败。
整个扩展变量将替换为评估返回的值。
如果使用的对象是使用Java实现的,则扩展变量语法允许您使用所谓的bean属性访问属性。实质上,这意味着如果你有一个将 getName
方法设置为变量$ {OBJ}
的对象,那么语法$ {OBJ.name}
相当于但比$ {OBJ.getName()}
更清晰 。因此,上一个示例中使用的Python对象可以替换为以下Java实现:
public class MyObject:
private String name;
public MyObject(String name) {
name = name;
}
public String getName() {
return name;
}
public String eat(String what) {
return name + " eats " + what;
}
public String toString() {
return name;
}
}
许多标准Python对象(包括字符串和数字)都具有可以显式或隐式使用扩展变量语法的方法。有时这可能非常有用并且减少了设置临时变量的需要,但是过度使用它并创建非常神秘的测试数据也很容易。以下示例显示了几个相当不错的用法。
请注意,即使在普通Python代码中建议使用abs(number)
而不是 数字.__ abs __()
,使用 $ {abs(number)}
也不起作用。这是因为变量名必须位于扩展语法的开头。 在这样的测试数据中使用__xxx__
方法已经有点疑问了,通常最好将这种逻辑移到测试库中。