创建变量

测试中可用的变量来源于各种不同的地方.

变量表格

变量最常见的源头就是在 测试用例文件资源文件 中的变量表格. 变量表格让变量和其它测试数据都创建在同一个地方, 而且语法也很简单, 因此使用起来非常方便. 不足之处在于这里变量的值只能是字符串, 并且不能动态创建. 要规避这些不足之处, 可以使用 变量文件.

创建标量变量

最简单的变量赋值操作就是将字符串赋值给一个标量变量.

在变量表格中的第一列指定变量名称(包括 ${}), 在第二列放上变量的值. 如果第二列为空, 则表示变量的值是空字符串. 值同时也可以是其它已经定义的变量.

  1. *** Variables ***
  2. ${NAME} Robot Framework
  3. ${VERSION} 2.0
  4. ${ROBOT} ${NAME} ${VERSION}

如果想要更明确的标示赋值操作, 可以在变量名称后面加上一个赋值等号 =, 这不是必需的.

  1. *** Variables ***
  2. ${NAME} = Robot Framework
  3. ${VERSION} = 2.0

如果一个标量变量的值很长, 可以分割到多列甚至 多行. 默认情况下, 各个单元格中的值最终会使用空格拼接起来, 不过可以在第一格中使用 SEPARATOR=<sep> 来指定连接符.

  1. *** Variables ***
  2. ${EXAMPLE} This value is joined together with a space
  3. ${MULTILINE} SEPARATOR=\n First line
  4. ... Second line Third line

上面的这种拼接方式是Robot Framework 2.9版本的新特性. 在2.8版本中, 这种格式会引发一个语法错误. 而在更早的版本中, 这会创建一个列表值.

创建列表变量

创建列表变量同样很简单. 变量名同样位于变量表格的第一列, 值位于后续的列. 一个列表变量可以有任意多的值, 包括0个值. 如果值比较多, 同样可以 分为多行.

  1. *** Variables ***
  2. @{NAMES} Matti Teppo
  3. @{NAMES2} @{NAMES} Seppo
  4. @{NOTHING}
  5. @{MANY} one two three four
  6. ... five six seven

创建字典变量

字典变量的创建方式类似列表. 不同之处在于字典的项需要使用 name=value 的语法格式, 或者其它的字典变量. 如果有多个项重名, 只保留最后那个. 如果项中包含字面的等号, 则该等号必须使用反斜杠进行 转义, 如 \=

  1. *** Variables ***
  2. &{USER 1} name=Matti address=xxx phone=123
  3. &{USER 2} name=Teppo address=yyy phone=456
  4. &{MANY} first=1 second=${2} ${3}=third
  5. &{EVEN MORE} &{MANY} first=override empty=
  6. ... =empty key\=here=value

字典变量相较于普通的Python字典有两个额外的属性(properties).

首先, 字典的项可以作为属性(attributes)获取, 也就是说使用 扩展变量语法${VAR.key}. 前提是该key是一个合法的属性名且不会匹配上任何其它普通的属性. 例如, &{USER}[name] 同样可以通过 ${USER.name} 获取(注意到这里是 $ ), 但是 ${MANY.3} 就不可以.

另一个特别之处在于字典变量中的项是有顺序的. 也就是说字典总是会按定义时的顺序迭代. 这在把字典当作 列表变量 使用时(例如在 FOR循环 )很有用. 当字典被当作列表迭代时, 实际返回的值是字典的键. 例如, @{MANY} 变量的值是 ['first', 'second', 3].

变量文件

变量文件是创建不同类型变量的强大武器. 使用变量文件可以给变量赋值为任意的对象, 同时还可以动态地创建变量. 关于变量文件的语法以及如何使用请参见 资源文件和变量文件.

命令行中设置变量

变量可以在命令行中通过选项 —variable (-v) 单个设置, 也可以通过选项 —variablefile (-V) 设置变量文件. 通过命令行设置的变量对所有执行的测试文件是全局可见的, 不过如果局部的变量表格或者局部导入的变量文件中存在重名的变量, 则这些变量也会被命令行中指定的值所覆盖.

设置单个变量的选项格式是 —variable name:value, 其中 name 是变量名, 不带 ${} value`是变量的值. 有多个变量的话就使用这个选项多次. 这种方式只能定义标量变量. 很多特殊字符必须使用选项 :option:–escape` 经过 转义 才能表示.

  1. --variable EXAMPLE:value
  2. --variable HOST:localhost:7272 --variable USER:robot
  3. --variable ESCAPED:Qquotes_and_spacesQ --escape quot:Q --escape space:_

在上例中, 变量值分别是:

  • ${EXAMPLE} 值为 value
  • ${HOST}${USER} 值分别为 localhost:7272robot
  • ${ESCAPED} 值为 "quotes and spaces"

在命令行中指定 变量文件 的选项格式是 —variablefile path/to/variables.py, 使用变量文件 章节中介绍更多细节.

如果变量同时在命令行的变量文件中和单独指定, 则单独指定的变量有更高的 优先级

关键字的返回值

关键字的返回值可以赋值给变量, 这样不同的关键字之间就可以交互了.

这种方式定义的变量和其它变量基本相同, 只是其作用域仅限于它们被创建的 local scope. 也就是说 不可能 在一个测试用例里得到这样一个返回值变量, 然后在另一个用例中使用. 因为自动化测试用例通常需要保持相互独立, 而不应该互相依赖. 如果用例中定义的变量可以在其它用例使用, 这将导致很难定位的错误. 但是如果确实有这种需求, 也可以通过下节介绍的 BuiltIn_ 中的相关关键字来实现.

赋值给标量

关键字返回的任何值都可以赋值给 标量变量. 如下例所示, 语法非常简单:

  1. *** Test Cases ***
  2. Returning
  3. ${x} = Get X an argument
  4. Log We got ${x}!

上例中, 关键字 Get X 的返回值首先赋值给变量 ${x} 然后又传给关键字 Log. 变量名称后面的等号(=)并不是强制要求的, 不过这种写法可以是赋值操作显得更明确.这种创建局部变量的方法同时适用于测试用例和用户关键字.

注意, 虽然值是赋给了标量变量, 但是其本身如果是一个列表(或类似列表), 则它也可以当做 列表变量 使用, 如果是一个类似字典的对象, 可以当做 字典变量 使用.

  1. *** Test Cases ***
  2. Example
  3. ${list} = Create List first second third
  4. Length Should Be ${list} 3
  5. Log Many @{list}

赋值给列表变量

如果关键字返回一个列表或者类似列表的对象, 则可以赋给 列表变量:

  1. *** Test Cases ***
  2. Example
  3. @{list} = Create List first second third
  4. Length Should Be ${list} 3
  5. Log Many @{list}

因为Robot Framework所有的变量都存储在相同的命名空间, 赋值给标量变量还是列表变量其实没有太多的差别. 最主要的差别就是当创建列表变量时, Robot Framework 自动校验值是否为列表或类似列表, 并且新建一个列表来保存返回的值. 当赋值给标量变量时, 返回值不会校验, 完全按照返回对象的类型保存值.

赋值给字典变量

如果关键字返回一个字典或者类似字典的对象, 则可以赋给 字典变量:

  1. *** Test Cases ***
  2. Example
  3. &{dict} = Create Dictionary first=1 second=${2} ${3}=third
  4. Length Should Be ${dict} 3
  5. Do Something &{dict}
  6. Log ${dict.first}

因为Robot Framework所有的变量都存储在相同的命名空间, 所以也可先把字典值赋值给标量变量, 后面再有需要时当作字典使用.

虽然如此, 但显式的创建字典变量也有实际的好处. 首先, Robot Framework会校验返回值确实是字典或者类似字典的对象.

另一个更大的好处是, 值会被转换保存为一个特殊的字典, 就像在变量表格中 creating dictionary variable 的那样, 可以通过获取属性值的语法 ${dict.first} 获取其中的值. 同时, 这个字典的顺序是固定的. 当然, 如果初始字典是无序的, 结果字典的顺序也是随机的.

赋值多个变量

如果一个关键字返回列表或类似列表的对象, 还可以一次性将其中的值同时赋值给多个变量. 可以是多个标量, 也可以是标量和列表混合, 如下例所示:

  1. *** Test Cases ***
  2. Assign Multiple
  3. ${a} ${b} ${c} = Get Three
  4. ${first} @{rest} = Get Three
  5. @{before} ${last} = Get Three
  6. ${begin} @{middle} ${end} = Get Three

假设关键字 Get Three 返回一个列表 [1, 2, 3] 会创建的变量如下:

  • ${a}, ${b}${c} 值分别是 1, 23
  • ${first} 值为 1, @{rest} 值为 [2, 3]
  • @{before} 值为 [1, 2], ${last} 值为 3
  • ${begin} 值为 1, @{middle} 值为 [2], ${end} 值为 3

如果返回的列表的元素个数多于或者少于可供赋值的标量, 将会报错. 另外, 待赋值的变量中最多只能有一个列表变量, 而字典变量只能单独赋值.

同时为多个变量赋值的特性功能在Robot Framework 2.9版本中有所变动. 早期版本中, 列表变量只被允许出现在待赋值变量的最后, 现在则可以是任意位置.

此外, 如果返回的值个数多于标量变量的个数, 最后一个标量会自动变为列表以包含剩下所有的值.

提示

译注, 这段存疑, 和前面矛盾了.实际测试结果是会报错.

Additionally, it was possible to return more values than scalar variables.In that case the last scalar variable was magically turned into a list containing the extra values.

使用关键字创建变量

BuiltIn_ 测试库提供了几个可以在测试执行时动态设置变量的关键字: Set Test Variable, Set Suite VariableSet Global Variable. 如果作用域内已经存在同名变量, 则会覆盖变量的值否则创建新的变量.

通过关键字 Set Test Variable 设置的变量在当前测试用例的作用域内处处可用. 例如, 在一个测试用例中的一个用户关键字中设置了一个变量, 该变量会在这个测试用例步骤可见, 同时当前用例中的其它用户关键字也可以使用这个变量. 这个关键字创建的变量在其它测试用例中不可用.

通过关键字 Set Suite Variable 创建的变量在当前执行的测试套件内处处可见. 使用这个方式创建变量和在测试数据文件的 变量表格 中定义变量, 以及从 变量文件 导入变量的效果一样. 这些变量对其它的测试套件, 包括子套件, 都不可见.

通过关键字 Set Global Variable 创建的变量在设置之后全局可见. 这种方式创建的变量和在 setting variables in command line 中使用选项 —variable—variablefile 定义变量效果一样. 因为这个关键字会改变任意地方的变量, 所以必须谨慎使用.

注解

关键字 Set Test/Suite/Global Variable 直接在 作用域内设置变量, 没有返回值. 而 Set Variable 设置局部变量, 并且 返回.