Maintainer: Rethink
Update: 2020/10/15
Robot Framework 3.2.1 (Python 3.7.0 on win32)
RF导入变量文件
在Setting中导入
Setting中导入变量文件时,和导入外部资源文件类似。变量文件的路径可以包含参数,如果一个变量文件接受参数,那么它们也可以是变量。
Path最好使用相对路径,如下:
*** Settings ***
Resource ../../eRes.txt
Variables ../test.py
Variables ../comVar.py product ${arg2}
Variables ${RESOURCES}/common.py
命令行导入
从命令行导入的Varialbe File,作用域范围是全局可用的。注意,-v
是导入变量,-V
才是导入变量文件。如果通过二者创建的变量名存在冲突,则-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 -*-
pystr = 'Brian'
pylist = ["大宗商品", "供应链金融", '2C电商']
pydict = {'username': 'Brian', 'passwd': '20171219'}
pyset = {"sing", 'jump'}
pytuple = ("age", "name", "sex")
_pykey = "f007688f401311e782617cd30ab49afc"
# __all__ = ['pystr', 'pylist', 'pydict']
在用例中的引用:
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的加为一个list;
- 为了更明确的定义list变量或者dict变量,可以在变量名称中加上前缀"LIST__" 或者 "DICT__"。RF中引用该变量时,不会把前缀当成变量名的一部分。前缀的作用是告诉RF该变量将会是"list-like"或者"dict-like"类型,框架会执行相应的检查验证。
LIST__pylist = ["大宗商品","供应链金融",'2C电商'] # prefix,list-like
DICT__pydict = {"username":"pyuser", "passwd":"20171219"} # prefix,dict-like
使用对象最为变量的值
变量文件中的变量不限于只有字符串或其他基本类型作为值,它们的变量可以包含任何对象。如下面的例子:
import datetime
dt = datetime.datetime.now
class MyObject:
def __init__(self, name):
self.name = name
@property
def first_name(self):
return self.name.split()[0]
john = MyObject('John Smith')
在用例中引用:
Log Many ${dt} ${dt()} ${dt().strftime('%Y-%m-%d')}
Log Many ${john} ${john.first_name}
输出内容如下:动态创建变量
由于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
YAML语法
变量文件也可以YAML文件实现。官方例子如下:
string: Hello, world!
integer: 42
list:
- one
- two
dict:
one: yksi
two: kaksi
with spaces: kolme
用例中的引用:
*** 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文件时不输入参数,则变量的值打印结果为:变量文件应用场景
一般来说,自动化测试的用例不仅只在测试环境运行,可能情况下有三套运行环境:测试环境、灰度环境(沙盒/预发布)、生产环境。调试或者辅助验证测试时,切环境改变量甚是麻烦。这些变量包括但不限于:一些url信息,数据库信息,预置用户信息等等。
对应以上需求,提供两种解决思路。
第一种思路是按照运行环境,把变量写入不同的变量文件。说测试环境的用到的变量写入testVars.py,生产环境下的变量写入productionVars.py,运行时根据环境pybot -V导入文件。
第二种思路是使用特殊函数,在一个文件中创建所有环境下需要的变量,函数入参为测试环境,默认参数为test,变量文件样例在上面已经给出了。