变量的类型
本节介绍不同的变量类型. 关于变量如何创建在下一节讨论.
Robot Framework 变量, 与关键字类似, 是不区分大小写的, 同时其中的下划线和空格也会被忽略.推荐使用大写字母来表示全局变量(如 ${PATH}
或 ${TWO WORDS}
), 小写字母来表示局部变量(如 ${my var}
或 ${myVar}
). 谨记, 关于大小写的使用风格要保持一致.
变量名称的构成包括: 一个表示变量类型的标识符($
, @
, &
, %
), 一对花括号({
, }
), 以及包含在花括号中的变量名.
不同于某些编程语言中变量的语法, 这里的花括号是不能省略的. 花括号内的变量名可以是任何字符, 但是推荐仅使用26个字母, 阿拉伯数字, 下划线和空格的组合. 同时, 如果使用了 扩展变量语法 还有更多的要求.
标量变量
当使用标量变量时, 变量被其赋值所替代. 最常用的标量赋值是字符串, 实际上标量可以是任何对象, 包括列表,字典等. 标量的语法格式对于大部分用户来说应该很熟悉, 这种格式在其它编程语言, 如shell脚本和Perl语言中, 都有使用.
下面的例子介绍了如何使用标量变量. 假设变量 ${GREET}
和 ${NAME}
在当前作用域内可用, 且分别被赋值为 Hello
和 world
. 例子中两个测试用例是等价的.
- *** Test Cases ***
- Constants
- Log Hello
- Log Hello, world!!
- Variables
- Log ${GREET}
- Log ${GREET}, ${NAME}!!
当一个标量变量在测试数据中独占一个单元格, 该变量被其赋值完全替代, 这个值可以是任何的对象.
如果单元格内还有其它内容(例如字符串或其它变量), 则变量的值会首先转换为Unicode字符串, 然后再和单元格内的其它内容拼接起来. 将对象转为字符串也就意味着要调用Python对象的 unicode
方法(如果没有则调用 str
), 或者Java对象的 toString
方法.
注解
变量作为关键字的参数使用 命名参数 语法时, 例如,argname=${var}
这时变量值会原样传递, 不做字符串转换.
下面的例子展示了当一个变量独占单元格和非独占时两者之间的区别. 首先, 假定变量 ${STR}
赋值为字符串 Hello, world!
, ${OBJ}
赋值为下面Java对象实例:
- public class MyObj {
- public String toString() {
- return "Hi, tellus!";
- }
- }
以下是测试用例:
- *** Test Cases ***
- Objects
- KW 1 ${STR}
- KW 2 ${OBJ}
- KW 3 I said "${STR}"
- KW 4 You said "${OBJ}"
当这个用例执行时, 不同的关键字接收到的参数解释如下:
- KW 1 接收到字符串 Hello, world!
- KW 2 接收到MyObj的对象实例 ${OBJ}
- KW 3 接收到字符串 I said “Hello, world!”
- KW 4 接收到字符串 You said “Hi, tellus!”
注解
如果变量不能表示为Unicode, 则这种转换显然会失败. 当发生这种情况时,例如, 用变量表示字节序列, 如果想要拼接在一起 ${byte1}${byte2}
传给关键字.这时的变通方案是创建一个包含所有值的变量(如 ${bytes}
)然后独占一个单元格, 这样避免发生转换.
列表变量
当变量作为标量使用, 如 ${EXAMPLE}
变量值按原样使用. 如果这个变量的值是一个列表, 或者类似列表的其它序列, 还可以将该变量作为列表变量使用, 格式为 @{EXAMPLE}
这种情况下, 列表中的元素会各自作为参数传递.
通过一个例子来解释会比较容易理解. 假设有一个变量 @{USER}
值是 ['robot', 'secret']
下例中两个测试用例是等价的:
- *** Test Cases ***
- Constants
- Login robot secret
- List Variable
- Login @{USER}
Robot Framework 将变量存储在一个内部空间中, 同时允许按照标量, 列表或字典的类型来使用它们. 按照列表来使用要求该值是一个Python列表或者类似列表的对象.
Robot Framework不允许字符串作为字符列表使用, 但是其它的序列对象如元组或字典是可以的.
Robot Framework 2.9版本之前, 标量和列表变量是分开存储的, 但是两者可以互换使用, 即列表变量作为标量使用, 标量变量作为列表使用. 当一个标量和列表变量同名但是不同值时, 这将引起很多混乱.
列表变量和其它数据混用
列表变量可以和其它参数混用, 其中可能还包含其它的列表参数.
- *** Test Cases ***
- Example
- Keyword @{LIST} more args
- Keyword ${SCALAR} @{LIST} constant
- Keyword @{LIST} @{ANOTHER} @{ONE MORE}
如果一个列表变量在单元格内和其它内容(比如字符串或其它变量)混用, 则最终的值会是该变量的字符串表示, 就跟标量变量的处理方式一样.
获取列表项
使用下标语法 @{NAME}[index]
可以获取到列表变量中指定项的值, 其中 index
是要获取的项的下标. 下标从0开始, 负数的下标等同于从列表末尾向前数. 下标长度超过列表范围会导致错误. 下标值自动转换为整数, 同样支持变量表示. 获取到的列表项基本等同于一个标量变量.
- *** Test Cases ***
- List Variable Item
- Login @{USER}[0] @{USER}[1]
- Title Should Be Welcome @{USER}[0]!
- Negative Index
- Log @{LIST}[-1]
- Index As Variable
- Log @{LIST}[${INDEX}]
在Setting中使用列表变量
列表变量可以在某些 设置项 中使用.
列表变量可以用在库和变量文件导入时的参数, 不过库和变量文件自身的名称不能是列表变量. Setup和Teardown中的关键字的参数也可以使用列表变量, 但是关键字名称不可以. 不过这些名称都支持使用标量型变量. 标签相关的设置可以自由使用列表变量.
- *** Settings ***
- Library ExampleLibrary @{LIB ARGS} # This works
- Library ${LIBRARY} @{LIB ARGS} # This works
- Library @{NAME AND ARGS} # This does not work
- Suite Setup Some Keyword @{KW ARGS} # This works
- Suite Setup ${KEYWORD} @{KW ARGS} # This works
- Suite Setup @{KEYWORD} # This does not work
- Default Tags @{TAGS} # This works
字典变量
如上所述, 包含列表的变量可以作为 列表变量, 将其中的项分别传递给关键字. 类似的, 一个变量包含Python的字典, 或者类似字典的对象, 可以当作字典变量使用, 如 &{EXAMPLE}
在实践中, 这意味着字典中的项可以作为 命名参数 传给关键字. 假设有个字典变量 &{USER}
中有值 {'name': 'robot', 'password': 'secret'}
, 则下面两个用例的效果是等价的.
- *** Test Cases ***
- Constants
- Login name=robot password=secret
- Dict Variable
- Login &{USER}
字典型变量是 Robot Framework 2.9 新增的特性.
字典变量和其它数据混用
字典变量可以和其它变量组合使用, 包括其它字典变量. 因为 命名参数 要求位置参数必须在命名参数之前, 所以字典变量后面只能跟命名参数或者其它的字典.
- *** Test Cases ***
- Example
- Keyword &{DICT} named=arg
- Keyword positional @{LIST} &{DICT}
- Keyword &{DICT} &{ANOTHER} &{ONE MORE}
如果一个字典变量在单元格内和其它内容(字符串或其它变量)混用, 最终的值会是变量的字符串表示, 就跟把变量当作标量变量的处理结果一样.
获取字典中的项
可以通过 &{NAME}[key]
这样的语法格式获取字典中某项的值, 其中 key
是键的名称.键名当作字符串处理, 非字符串的键可以用变量代替. 通过这种方式获取到的值可作为标量变量使用.
如果键是字符串, 还可以使用另一种语法格式 ${NAME.key}
. 更多细节说明请参考 创建字典变量
- *** Test Cases ***
- Dict Variable Item
- Login &{USER}[name] &{USER}[password]
- Title Should Be Welcome &{USER}[name]!
- Key As Variable
- Log Many &{DICT}[${KEY}] &{DICT}[${42}]
- Attribute Access
- Login ${USER.name} ${USER.password}
- Title Should Be Welcome ${USER.name}!
在Setting中使用字典变量
字典变量除了在import, setup, teardown中充当关键字的参数使用, 不能在其它设置项中使用.
- *** Settings ***
- Library ExampleLibrary &{LIB ARGS}
- Suite Setup Some Keyword &{KW ARGS} named=arg
环境变量
Robot Framework使用 %{ENV_VAR_NAME}
这种语法格式来使用环境变量. 环境变量的值只能是字符串.
在测试执行前已设置的操作系统环境变量在执行过程中都是可用的, 同时还可以使用关键字 Set Environment Variable 创建新的环境变量, 或者 Delete Environment Variable 删除某个环境变量, 这两个关键字都是来自于 OperatingSystem 库.
因为环境变量是全局的, 所以在一个测试用例中设置的环境变量可以在后续执行的另一个测试用例中使用. 不过, 测试执行中改变的环境变量在测试执行完成后即恢复原状, 即不会真正改变系统的环境变量.
- *** Test Cases ***
- Env Variables
- Log Current user: %{USER}
- Run %{JAVA_HOME}${/}javac
Java系统属性
当使用Jython运行测试时, 可以使用 环境变量 的语法来获取 Java系统属性. 如果一个环境变量的名称和一个系统属性重名, 则最终返回的是环境变量的值.
- *** Test Cases ***
- System Properties
- Log %{user.name} running tests on %{os.name}