Robot Framework(八) 资源和变量文件
2.7资源和变量文件
测试用例文件和测试套件初始化文件中的用户关键字和变量只能在创建它们的文件中使用,但资源文件提供了共享它们的机制。由于资源文件结构非常接近测试用例文件,因此很容易创建它们。
变量文件提供了一种创建和共享变量的强大机制。例如,它们允许除字符串以外的值,并允许动态创建变量。它们的灵活性来自于它们是使用Python代码创建的,这也使它们比Variable表更复杂。
2.7.1资源文件
使用资源文件
使用“ 设置”表中的“ 资源”设置导入资源文件。资源文件的路径在设置名称后面的单元格中给出。
如果路径以绝对格式给出,则直接使用。在其他情况下,首先相对于导入文件所在的目录搜索资源文件。如果在那里找不到该文件,则从PYTHONPATH中的目录中搜索该文件。路径可以包含变量,建议使用它们使路径与系统无关(例如,$ {RESOURCES} /login_resources.html或 $ {RESOURCE_PATH})。此外,路径中的斜杠(“/”)会自动更改为Windows上的反斜杠(“\”)。
设置 | 值 | 值 |
---|---|---|
资源 | myresources.html | |
资源 | ../data/resources.html | |
资源 | $ {}资源/common.tsv |
资源文件中定义的用户关键字和变量在获取该资源文件的文件中可用。同样可用的还有来自由所述资源文件导入的库,资源文件和变量文件的所有关键字和变量。
资源文件结构
资源文件的更高级结构与测试用例文件的结构相同,但是,当然,它们不能包含测试用例表。此外,资源文件中的设置表只能包含导入设置(库,资源, 变量)和文档。Variable表和Keyword表的使用方式与测试用例文件完全相同。
如果多个资源文件具有相同名称的用户关键字,则必须使用它们,以便关键字名称以不带扩展名的资源文件名为前缀(例如,myresources.Some Keyword和common.Some Keyword)。此外,如果多个资源文件包含相同的变量,则首先导入的变量将被使用。
记录资源文件
可以使用 [Documentation]设置记录在资源文件中创建的关键字。从Robot Framework 2.1开始,资源文件本身也可以像设置测试套件一样在设置表中使用文档。
无论libdoc和RIDE使用这些文档,和他们自然可以为任何人打开资源文件。关键字文档的第一行在运行时会被记录,但在测试执行期间会忽略资源文件文档。
示例资源文件
设置 | 值 | 值 | 值 |
---|---|---|---|
文档 | 示例资源文件 | ||
图书馆 | SeleniumLibrary | ||
资源 | $ {}资源/common.html |
变量 | 值 | 值 | 值 |
---|---|---|---|
$ {HOST} | 本地主机:7272 | ||
$ {} LOGIN_URL | HTTP:// $ {HOST} / | ||
$ {} WELCOME_URL | HTTP:// $ {HOST} /welcome.html | ||
$ {} BROWSER | 火狐 |
关键词 | 行动 | 争论 | 争论 | 争论 |
---|---|---|---|---|
打开登录页面 | [文档] | 打开浏览器 | 登录页面 | |
打开浏览器 | $ {} LOGIN_URL | $ {} BROWSER | ||
标题应该是 | 登录页面 | |||
输入名称 | [参数] | $ {NAME} | ||
输入文本 | username_field | $ {NAME} | ||
输入密码 | [参数] | $ {}密码 | ||
输入文本 | password_field | $ {}密码 |
2.7.2变量文件
变量文件包含可在测试数据中使用的变量。变量也可以使用变量表创建或从命令行设置,但变量文件允许动态创建它们,并且它们的变量可以包含任何对象。
变量文件通常实现为Python模块,有两种不同的方法可用于创建变量:
- 直接创建变量
- 变量被指定为模块属性。在简单的情况下,语法非常简单,不需要真正的编程。例如, MY_VAR ='my value'创建一个变量 $ {MY_VAR},并将指定的文本作为值。
- 从特殊函数中获取变量
- 变量文件可以有一个特殊的get_variables (或getVariables)方法,它将变量作为映射返回。因为该方法可以采用参数,所以这种方法非常灵活。
或者,变量文件可以实现为 框架将实例化的Python或Java类。同样在这种情况下,可以将变量创建为属性或从特殊方法获取它们。
使用可变文件
设置表
所有测试数据文件都可以使用“ 设置”表中的“ 变量”设置导入变量 ,方法与使用“ 资源” 设置导入资源文件的方式相同 。与资源文件类似,导入变量文件的路径被认为是相对于导入文件所在的目录,如果没有找到,则从PYTHONPATH中的目录中搜索。路径也可以包含变量,斜杠在Windows上转换为反斜杠。如果参数文件接受参数,则它们在路径之后的单元格中指定,并且它们也可以包含变量。
设置 | 值 | 值 | 值 |
---|---|---|---|
变量 | myvariables.py | ||
变量 | ../data/variables.py | ||
变量 | ${RESOURCES}/common.py | ||
变量 | taking_arguments.py | arg1 | ${ARG2} |
变量文件中的所有变量都可以在导入它的测试数据文件中找到。如果导入了多个变量文件并且它们包含具有相同名称的变量,则最早导入的文件中的变量文件将被使用。此外,在变量表中创建并从命令行设置的变量会覆盖变量文件中的变量。
命令行
使用变量文件的另一种方法是使用命令行选项 --variablefile。可变文件是使用将它们的路径引用的,以及可能的参数被连接到路径用冒号(:):
--variablefile myvariables.py --variablefile path / variables.py --variablefile /absolute/path/common.py --variablefile taking_arguments.py:arg1:arg2
这些文件中的变量在所有测试数据文件中全局可用,类似于使用--variable选项设置的 单个变量。如果同时使用了--variablefile和 --variable选项,并且存在具有相同名称的变量,那么使用--variable选项单独设置的变量 优先。
直接创建变量
基本语法
当使用变量文件时,它们将作为Python模块导入,并且所有不以下划线(_)开头的全局属性都被视为变量。由于变量名称不区分大小写,因此可以使用小写和大写名称,但通常,建议使用大写字母表示全局变量和属性。
VARIABLE = "An example string"
ANOTHER_VARIABLE = "This is pretty easy!"
INTEGER = 42
STRINGS = ["one", "two", "kolme", "four"]
NUMBERS = [1, INTEGER, 3.14]
在上面的示例中,创建了变量$ {VARIABLE}, $ {ANOTHER VARIABLE}等。前两个变量是字符串,第三个是整数,后两个是列表。所有这些变量都是标量变量,甚至是包含列表作为值的变量。要创建列表变量,变量名称必须以LIST__为前缀(注意两个下划线)。
LIST__STRINGS = ["list", "of", "strings"]
LIST__MIXED = ["first value", -1.1, None, True]
上面两个示例中的变量也可以使用下面的Variable表创建。
Variable | Value | Value | Value | Value |
---|---|---|---|---|
${VARIABLE} | An example string | |||
${ANOTHER_VARIABLE} | This is pretty easy! | |||
${INTEGER} | ${42} | |||
${STRINGS} | one | two | kolme | four |
${NUMBERS} | ${1} | ${INTEGER} | ${3.14} | |
@{STRINGS} | list | of | strings | |
@{MIXED} | first value | ${-1.1} | ${None} | ${True} |
使用对象作为值
变量文件中的变量不仅限于将字符串或其他基类型作为变量表之类的值。相反,它们的变量可以包含任何对象。在下面的示例中,变量 $ {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')
动态创建变量
因为变量文件是使用真实的编程语言创建的,所以它们可以具有用于设置变量的动态逻辑。
import os
import random
import time
USER = os.getlogin() # current login name
RANDOM_INT = random.randint(0, 10) # random integer in range [0,10]
CURRENT_TIME = time.asctime() # timestamp like 'Thu Apr 6 12:45:21 2006'
if time.localtime()[3] > 12:
AFTERNOON = True
else:
AFTERNOON = False
上面的示例使用标准Python库来设置不同的变量,但您可以使用自己的代码来构造值。下面的示例说明了这个概念,但同样地,您的代码可以从数据库,外部文件中读取数据,甚至可以从用户那里获取数据。
import math
def get_area(diameter):
radius = diameter / 2
area = math.pi * radius * radius
return area
AREA1 = get_area(1)
AREA2 = get_area(2)
选择要包含的变量
当Robot Framework处理变量文件时,所有不以下划线开头的属性都应该是变量。这意味着即使在变量文件中创建或从其他地方导入的函数或类也被视为变量。例如,除了$ {AREA1}和 $ {AREA2}之外,最后一个示例将包含变量$ {math} 和$ {get_area }。
通常,额外的变量不会导致问题,但是它们可能会覆盖其他一些变量并导致难以调试的错误。忽略其他属性的一种可能性是在前面添加下划线:
import math as _math
def _get_area(diameter):
radius = diameter / 2.0
area = _math.pi * radius * radius
return area
AREA1 = _get_area(1)
AREA2 = _get_area(2)
如果存在大量其他属性,而不是为它们添加前缀,则通常更容易使用特殊属性 __all__并为其提供要作为变量处理的属性名称列表。
import math
__all__ = ['AREA1', 'AREA2']
def get_area(diameter):
radius = diameter / 2.0
area = math.pi * radius * radius
return area
AREA1 = get_area(1)
AREA2 = get_area(2)
注意
当使用modulename import*中的语法时,python还最初使用uu all_uuu属性来决定导入哪些属性。
从特殊函数中获取变量
获取变量的另一种方法是在变量文件中使用特殊的 get_variables函数(也可以使用camelCase语法 getVariables)。如果存在这样的函数,Robot Framework会调用它并期望将变量作为Python字典或Java Map接收,其中变量名称作为键,变量值作为值。变量被认为是标量,除非前缀为LIST__,值可以包含任何内容。下面的示例在功能上与上面直接创建变量的第一个示例相同 。
def get_variables():
variables = {"VARIABLE ": "An example string",
"ANOTHER_VARIABLE": "This is pretty easy!",
"INTEGER": 42,
"STRINGS": ["one", "two", "kolme", "four"],
"NUMBERS": [1, 42, 3.14],
"LIST__STRINGS": ["list", "of", "strings"],
"LIST__MIXED": ["first value", -1.1, None, True]}
return variables
get_variables也可以使用参数,这有助于更改实际创建的变量。该函数的参数设置与Python函数的任何其他参数一样。当考虑可变文件到使用在所述测试数据,自变量在细胞中的路径,变量文件后指定,并且在命令行它们从用冒号路径分离。
下面的虚拟示例显示了如何将参数与变量文件一起使用。在一个更现实的例子中,参数可以是外部文本文件或数据库的路径,从中读取变量。
variables1 = {'scalar': 'Scalar variable',
'LIST__list': ['List','variable']}
variables2 = {'scalar' : 'Some other value',
'LIST__list': ['Some','other','value'],
'extra': 'variables1 does not have this at all'}
def get_variables(arg):
if arg == 'one':
return variables1
else:
return variables2
将变量文件实现为Python或Java类
从Robot Framework 2.7开始,可以将变量文件实现为Python或Java类。
履行
由于变量文件始终使用文件系统路径导入,因此将它们创建为类具有一些限制:
- Python类必须与它们所在的模块具有相同的名称。
- Java类必须存在于默认包中。
- Java类的路径必须以.java或.class结尾。两种情况下都必须存在类文件。
无论实现语言如何,框架都将使用无参数创建类的实例,并且将从实例获取变量。与模块类似,变量可以直接在实例中定义为属性,也可以从特殊的get_variables (或getVariables)方法获取。
当直接在实例中定义变量时,将忽略包含可调用值的所有属性,以避免从实例具有的可能方法创建变量。如果您确实需要可调用变量,则需要使用其他方法来创建变量文件。
例子
第一个示例使用Python和Java从属性创建变量。它们都从类属性创建变量$ {VARIABLE}和@ {LIST},从实例属性创建$ {ANOTHER VARIABLE}。
class StaticPythonExample(object):
variable = 'value'
LIST__list = [1, 2, 3]
_not_variable = 'starts with an underscore'
def __init__(self):
self.another_variable = 'another value'
public class StaticJavaExample {
public static String variable = "value";
public static String[] LIST__list = {1, 2, 3};
private String notVariable = "is private";
public String anotherVariable;
public StaticJavaExample(String arg1, String arg2) {
anotherVariable = "another value";
}
}
第二个例子利用动态方法获取变量。它们都只创建一个变量$ {DYNAMIC VARIABLE}。
class DynamicPythonExample(object):
def get_variables(self, *args):
return {'dynamic variable': ' '.join(args)}
import java.util.Map;
import java.util.HashMap;
public class DynamicJavaExample {
public Map<String, String> getVariables(String arg1, String arg2) {
HashMap<String, String> variables = new HashMap<String, String>();
variables.put("dynamic variable", arg1 + " " + arg2);
return variables;
}
}