在测试过程当中,测试数据往往会与代码进行分离,进行独立存储。
存储或获取测试数据的方式有很多,如excel文件中、txt文件中、yaml文件中、或者从数据库中读取。
今天我们要说的就是怎样从yaml文件中获取数据。
一、认识python中的yaml库
安装:安装包名是pyyaml
导入:import yaml
注意:安装是pyyaml,导入是yaml
二、读取文件格式
可读取 .yaml和 .yml格式的文件。
三、获取数据的大体思路
1、open 文件,读取文件数据。
2、使用yaml库中load相关方法将文件数据转换为字典格式。
四、yaml之load()、load_all():
先看load()的源码:
def load(stream, Loader=None): """ Parse the first YAML document in a stream and produce the corresponding Python object. """ if Loader is None: load_warning('load') Loader = FullLoader loader = Loader(stream) try: return loader.get_single_data() finally: loader.dispose()
load方法的作用是:解析文件流中的第一个YAML文件,并生成一个Python对象(dict类型字典)。
tips:其实对于yaml文件,可以用 --- 在一个.YAML文件中定义多个YAML文件。
如下图,每个---下的数据为一个YAML document:
--- test1: account1: "tom" password1: "111111" test2: account2: "jerry" password2: "111111" --- test3: account3: "TMC" password3: "111111"
那么,yaml库中也提供了读取多个YAML文件的.yaml文件:load_all()
我们看一下load_all()的源码:
def load_all(stream, Loader=None): """ Parse all YAML documents in a stream and produce corresponding Python objects. """ if Loader is None: load_warning('load_all') Loader = FullLoader loader = Loader(stream) try: while loader.check_data(): yield loader.get_data() finally: loader.dispose()
load_all返回一个generator对象,即一个生成器对象。
我们知道,对于generator类型对象,可以用next()来逐一获取每个yaml document的内容。
举个栗子:
test.yaml文件:
--- test1: account1: "tom" password1: "111111" test2: account2: "jerry" password2: "111111" --- test3: account3: "TMC" password3: "111111"
获取yaml文件代码如下:
import yaml with open("test.yaml", "r", encoding="utf-8") as f: date_yaml = yaml.load_all(f) print(type(date_yaml)) print(next(date_yaml)) print(next(date_yaml))
我们调用了load_all对象,对每一个yaml document的内容,用next(generator对象来获取)
执行结果如下:
<class 'generator'> {'test1': {'account1': 'tom', 'password1': '111111'}, 'test2': {'account2': 'jerry', 'password2': '111111'}} {'test3': {'account3': 'TMC', 'password3': '111111'}}
我们可以看到,每调用一次next(date_yaml)就获得一个yaml document数据。这也是生成器的特性。
tips:对于load()和load_all()都会报错warnning,为了不报warnning,应该使用safe_load()和safe_load_all()最为理想。
总结:
1,用safe_load()和safe_load_all()来代替 load()和load_all()
2,若.yaml文件中只有一个YAML document,则使用safe_load(),以字典形式返回内容
3,若.yaml文件中有多个YAML document,则使用safe_load_all(),返回一个生成器(generator),生成器通过next(生成器)的方式获取每一个
YAML document中的内容。
五、unittest自动化框架中,读取yaml文件内容的工具封装:
import yaml import os path = os.path.dirname(os.path.dirname(__file__)) + "\\data\\" def get_yaml_data(yaml_filename, file_path=path): """ 获取yaml数据 :param file_path: 文件路径,默认项目中data包路径 :param yaml_filename: yaml文件全称, 如:'login.yaml' :return: 列表嵌套字典格式的数据 """ yaml_file = file_path + yaml_filename with open(yaml_file, 'r', encoding='utf-8') as f: data = f.read() yaml_data = yaml.safe_load(data) return yaml_data
思路:
1、获取测试数据文件的路径path。
2、定义函数,接收文件名和测试数据文件夹路径(默认path)。
3、拼接1,和 2,形成测试yaml文件的完整路径。
4、打开测试文件,并读取文件数据。
5、load数据并返回。
tips:如果测试文件是多个YAML document,则可再封装一个读取多个YAML document的工具;