RF导入变量文件
在Setting中导入
Setting中导入变量文件时,和导入外部资源文件类似。变量文件的路径可以包含参数,如果一个变量文件接受参数,那么它们也可以是变量。
Path最好使用相对路径,如下:
*** Settings ***
Resource ../../eRes.txt
Variables ../test.py
Variables ../comVar.py product ${arg2}
Variables ${RESOURCES}/common.py
Ride 中导入变量文件:
命令行导入
pybot --help
查看相关帮助信息如下:
从命令行导入的Varialbe File,作用域范围是全局可用的。注意,pybot -v 是导入变量,pybot -V 才是导入变量文件。如果通过 pybot -v 和 pybot -V 创建的变量名存在冲突,则pybot -v选项创建的变量将会被保留。
如果变量文件需要参数,则可以使用冒号来分隔path和params。如果在Winodws系统中使用绝对路径导入变量文件,则驱动器号后面的冒号不会被认为是一个分隔符:如下:
pybot --variablefile /relative_path/variables.py #相对路径
pybot -V /absolute_path/common.py #绝对路径
pybot -V C:\path\variables.py #绝对路径
pybot -V ../common.py:product #变量文件有一个参数
pybot -V needTwoParams.py:arg1:arg2 #变量文件有多个参数
pybot -V "../common.py:product" -V "../test.py" #导入多个变量文件
如果多个文件导入时存在变量重名的情况,则最先导入的变量有效 。
创建变量文件
直接创建
基本语法
在变量文件中直接给变量赋值,语法非常简单,变量名大小写不敏感。
# -*- coding: utf-8 -*-
# python
pyuser = 'Brian' # 在RF中等同于:${pyuser} |Set Variable |'Brian'
pytags = ["大宗商品","供应链金融",'2C电商'] # list
pyparams = {'username':'Brian','passwd':'20171219'}
_pykey = "f007688f401311e782617cd30ab49afc"
__all__ = ['pyuser','pytags'] #变量名需要加引号
RF中的写法:
#rf中的写法
log many ${pyuser} ${pytags} ${pyparams}
${pytags} Evaluate '${pytags}'.decode('utf8')
${type_pyuser} Evaluate type($pyuser)
${type_pytags} Evaluate type($pytags)
${type_pyparams} Evaluate type($pyparams)
补充几点:
- 变量文件中创建的所有以下划线开头的变量不会被RF导入,如 ''_pykey'' ;除此之外,也可以使用''__all__'' (双下滑线)将真正要被RF导入的Variables的加为一个lis;比如上面的例子中,就只有pyuser和pytags被认为是variable,而pyparams将会被忽略;
- 为了更明确的定义list变量或者dict变量,可以在变量名称中加上前缀"LIST__" (两个下划线)或者 "DICT__"。RF中引用该变量时,不会把前缀当成变量名的一部分。前缀的作用是告诉RF该变量将会是"list-like"或者"dict-like"类型,框架会执行响应的检查验证。
LIST__pytags = ["大宗商品","供应链金融",'2C电商'] # prefix,list-like
DICT__pyparams = {"username":"pyuser", "passwd":"20171219"} # prefix,dict-like
- 变量文件中创建的Set类型或Tuple类型的变量,应该避免在RF中引用,否则可能会报语法错误;
- 通常来说,全局变量名称应该大写,非全局变量小写;
使用对象最为变量的值
变量文件中的变量不限于只有字符串或其他基本类型作为值。相反,它们的变量可以包含任何对象。在下面的示例中,变量$ {MAPPING}包含一个具有两个值的Java Hashtable(这个示例只在Jython上运行测试时才起作用)。
from java.util import Hashtable
MAPPING = Hashtable()
MAPPING.put("one", 1)
MAPPING.put("two", 2)
第二个示例创建了$ {MAPPING}作为Python字典,并且还包含两个从同一个文件中实现的自定义对象创建的变量。
MAPPING = {'one': 1, 'two': 2}
class MyObject:
def __init__(self, name):
self.name = name
OBJ1 = MyObject('John')
OBJ2 = MyObject('Jane')
动态创建变量
由于Variable File本质上是编程语言进行变量的创建,所以可以达到动态创建变量的效果。
import os
import random
import time
import datetime
PATH = os.getcwd() #获得当前路径
RANDOM_INT = random.randint(0,9999) #random integer in range [0,9999]
CURRENT_TIME = time.time() # 1513661957.0591035
NOW = datetime.datetime.now() #2017-12-19
YEAR = NOW.year
MONTH = NOW.month
HOUR = NOW.hour
RF中打印变量的值如下:
YAML语法
变量文件也可以YAML文件实现。官方例子如下:
string: Hello, world!
integer: 42
list:
- one
- two
dict:
one: yksi
two: kaksi
with spaces: kolme
#RF中的写法
*** Variables ***
${STRING} Hello, world!
${INTEGER} ${42}
@{LIST} one two
&{DICT} one=yksi two=kaksi
使用特殊函数
如果在Variable File中存在特殊函数(getVariables、get_variable),可以通过特殊函数来得到变量,此机制使得变量的创建变的非常灵活。
如果特殊函数存在,RF框架会调用此函数来获取函数。 函数的预期返回应该是Python的dict 或者 Java的Map, 其中key为Variable名称, value为Variable值。 其他规则和直接创建变量的情形一样:,既可以创建scalar, list, dict各种类型的变量,也支持特殊前缀"LIST__" 和 "DICT__"等。
# -*- coding: utf-8 -*-
def getVariables(env = 'test'):
if env == 'product':
#production environment
DICT__variables = {
"dbPort" : "3308",
"dbUser": "qt_product",
"dbPasswd" : "qt_product",
}
else :
#test environment
DICT__variables = {
"dbPort" : "3309",
"dbUser": "qt_test",
"dbPasswd" : "qt_test",
}
#全局变量,不区分运行环境
globalvars = {'projectID':'3456','userID':'6'}
DICT__variables['globalvars'] = globalvars #RF中取值用${globalvars['userID']}
return DICT__variables
如果在RF中引入该Variable file文件时不输入参数,则变量的值打印结果为:
如果输入参数product,则变量的值打印结果为:
切换运行环境
一般来说,自动化测试的用例不仅只在测试环境运行,可能情况下有三套运行环境:测试环境、灰度环境(沙盒/预发布)、生产环境。调试或者辅助验证测试时,切环境改变量甚是麻烦。这些变量包括但不限于:一些url信息,数据库信息,预置用户信息等等。
对应以上需求,提供以下解决思路。
第一种思路是按照运行环境,把变量写入不同的变量文件。说测试环境的用到的变量写入testVars.py,生产环境下的变量写入productionVars.py,运行时根据环境pybot -V导入文件。
第二种思路是使用特殊函数,在一个文件中创建所有环境下需要的变量,函数入参为测试环境,默认参数为test,变量文件样例在上面已经给出了。
最后,我们来探讨一下,所谓的RF的全局变量,想要只在用例里改变它的值,并且后续用例里用改变后的值,提供思路:通过变量文件,利用字典update方法将改变内存里的值的特性。
如上面的例子中,变量文件中定义了一个变量projectID:
globalvars = {'projectID':'3456','userID':'6'}
DICT__variables['globalvars'] = globalvars
下图中两个suite 文件Test1和Test2都导入了该变量文件,在Test1下的case1中更新该变量的值,在Test2的case2下,它的值还是6666,如果再次用update的方法更新时,后续所有的Case中的值都会是更新后的值。如此,达到用例中间变更变量后续可用的目的。