常用的配置文件类型

在做自动化测试中,配置文件常用的有 2 种。
第一种是.ini 文件,实际上.ini 文件是 Initialization file 的缩写,即为初始化文件,是 Windows 系统配置文件所采用的存储格式,统管 Windows 的各项配置,用户可以通过修改对应的 *.ini 文件来实现不同的初始化配置
第二种是 yaml 文件,YML 文件格式是 YAML (YAML Aint Markup Language) 编写的文件格式,YAML 是一种直观的能够被电脑识别的的数据数据序列化格式。
下面就主要介绍下 ini 文件以及 yaml 文件的使用。

ini 文件

什么是 ini

ini 文件是 Initialization File 的缩写,即初始化文件,通常存放的是一个程序的初始化信息,是 Windows 的系统配置文件所采用的存储格式,统管 windows 的各项配置。ini 文件的后缀名不一定是.ini,也可以是.cfg、.conf 或者是.tx*。

ini 文件格式&语法规范

ini 文件由若干个节(section)组成,每个 section 由若干键(Key)组成,每个 Key 可以赋相应的值。读写 ini 文件实际上就是读写某个的 section 中相应的 Key 的值,而这只要借助几个函数即可完成。

name=value
[section]
;i wish nothing but the best for you        

文件实例

[owner]
name=WU yanzu
organization=The United Nations

[UserConfig]
OpenDownloadFileAtOnec=Y
WindowStyle=DevExpress Dark Style

[Language]
Language=CHS

[AutoUpdate]
Version=2.10  ;last version:2.08

注意点

ini 文件操作

import configparser

"""读取ini文件中节点/选项/选项值"""
config = configparser.ConfigParser()
config.read("config.ini")

"""读取ini文件所有的节点"""
selections = config.sections()
print(f"文件中所有的节点:{selections}", type(selections))
print("--------------------------------------------------")

"""获取每个节点下的选线"""
for selection in selections:
    options = config.options(selection)
    print(f"{selection}节点所有的选项:{options}", type(options))
    """获取选项值"""
    for option in options:
        value = config.get(selection,option)
        print(f"{selection}节点{option}选项的值:{value}")
print("--------------------------------------------------")

"""获取指定节点下的所有options"""
options = config.options("server")
print(f"获取指定节点(server)下的选项:{options}", type(options))
print("--------------------------------------------------")

"""获取指定节点指定选项的值"""
value = config.get(section="server",option="ip")
print(f"获取指定节点(server)下的(ip)的值:{value}")
print("--------------------------------------------------")

"""判断是否有指定的selection"""
print(f"判断是否有指定的server节点:", config.has_section("server"))
print("--------------------------------------------------")

"""判断是否有指定的option"""
print(f"判断在在指定的节点server下是否有指定的ip选项:", config.has_option("server", "ip"))
print("--------------------------------------------------")

config1 = configparser.ConfigParser()
with open("config.ini", "a+") as file:
    """添加节点"""
    config1.add_section("data")
    """添加选项以及选项值"""
    config1.set(section="data", option="TestName", value="Test01")
    config1.set(section="data", option="TestPassWd", value="12345678")
    """移除选项"""
    config1.remove_option(section="data",option="TestPassWd")
    """移除节点"""
    config1.remove_section(section="data")
    config1.write(file)
from configparser import ConfigParser
import os
"""
继承ConfigParser类
然后初始化编码格式
"""
class ReadConf(ConfigParser):
    def __init__(self,file_path):
        super().__init__()
        self.read(filenames=file_path,encoding='utf-8')

file_path = os.path.join(os.path.dirname(__file__), 'test.ini')
conf=ReadConf(file_path=file_path)

#使用直接导入conf实例
from confFile.conffengzhuang import conf
values = conf.options('log1')
print(values)
输出['key1', 'key2']

yaml 文件

什么是 yaml

YAML 是一种广泛使用的语言,用于跨不同语言和框架的配置文件。专注于简化 XML 的 XML 人员名单帮助生成 Common XML,这是一个功能强大的 XML 子集,为 XML 创建了数据序列化的替代方案,特别是与 Python ,Perl 和 Ruby。它的可读性和可编辑性感觉比 json 高,支持 C++ 强类型。YAML 文件可视为二维。有些库支持配置引用。有些库支持配置引用。

yaml 文件格式&语法格式

yaml 文件操作

import yaml

def get_yaml_data(yaml_file):
    print("*****获取yaml数据*****")
    with open(yaml_file, encoding='utf-8') as file:
        content = file.read()
        print(content)
        print(type(content))

        print("*****转换yaml数据为字典或列表*****")
        # 设置Loader=yaml.FullLoader忽略YAMLLoadWarning警告
        data = yaml.load(content, Loader=yaml.FullLoader)
        print(data)
        print(type(data))
        print(data.get('my'))  # 类型为字典 <class 'dict'> # print(data[0]["model"]) # 若类型为列表 <class 'list'>


if __name__ == "__main__":
    get_yaml_data("config.yaml")
user: my
pwd: 1111
*****获取yaml数据*****
# yaml键值对:即python中的字典
user: my
pwd: 1111
<class 'str'>

*****转换yaml数据为字典或列表*****
{'user': 'my', 'pwd': 1111}
<class 'dict'>
my
user1:
  name: a
  pwd: 111222
user2:
  name: b
  pwd: 222333
*****获取yaml数据*****
user1:
  name: a
  pwd: 111222
user2:
  name: b
  pwd: 222333
<class 'str'>

*****转换yaml数据为字典或列表*****
{'user1': {'name': 'a', 'pwd': 111222}, 'user2': {'name': 'b', 'pwd': 222333}}
<class 'dict'>
{'name': 'a', 'pwd': 111222}
user3:
  - a
  - b
user4:
  - d
  - e
*****获取yaml数据*****
user3:
  - a
  - b
user4:
  - d
  - e
<class 'str'>

*****转换yaml数据为字典或列表*****
{'user3': ['a', 'b'], 'user4': ['d', 'e']}
<class 'dict'>
['a', 'b']
s_val: hello world
num_val: 15
bol_val: true
nul_val: null
data_val: 2020-08-17
*****获取yaml数据*****
s_val: hello world
num_val: 15
bol_val: true
nul_val: null
data_val: 2020-08-17
<class 'str'>

*****转换yaml数据为字典或列表*****
{'s_val': 'hello world', 'num_val': 15, 'bol_val': True, 'nul_val': None, 'data_val': datetime.date(2020, 8, 17)}
<class 'dict'>
hello world
current_path = os.getcwd()
path = os.path.join(current_path, 'config.yaml')

aproject = {'name': 'Silenthand Olleander',
            'race': '哈哈哈黑',
            'traits': ['ONE_HAND', 'ONE_EYE']
            }

# 写
with open(path, 'w', encoding='utf-8')as f1:
    # 字符串写入yaml中
    yaml.dump(aproject, f1, default_flow_style=False, encoding='utf-8', allow_unicode=True)

# 读
with open(path, 'r', encoding='utf-8')as f2:
    # 读取,此时读取出来的是字符串
    data = f2.read()
    # 将读取的内容转化成字典
    # 添加Loader=yaml.FullLoader,不然会有warning
    result = yaml.load(data, Loader=yaml.FullLoader)
    print(result)
import yaml
import os

current_path = os.getcwd()
path = os.path.join(current_path, 'config.yaml')

user1 = {
    'name': '张三',
    'age': 18,
    'like': {'kecheng': '语文','yundong': '跑步'}
}

user2 = {
    'name': '李四',
    'age': 17,
    'like': {'kecheng': '数学','yundong': '跳高'}
}

# 写
with open(path, 'w', encoding='utf-8')as f1:
    # 字符串写入yaml中
    yaml.dump_all([user1, user2], f1, default_flow_style=False, encoding='utf-8', allow_unicode=True)

# 读
with open(path, 'r', encoding='utf-8')as f2:
    data = f2.read()
    # 添加Loader=yaml.FullLoader,不然会有warning
    result = yaml.load_all(data, Loader=yaml.FullLoader)
    for i in result:
        print(i)

import yaml, os

class YamlUtil():

    def __init__(self, yaml_path):
        self.yaml_path = yaml_path

    def get_yml_data(self, is_modify=False, *key_names):
        """
        读取yaml配置文件并根据对应层级的key获取对应的value
        适用于两层数据
        :param: key_names: 需要查询的yaml文件的key关键字,从左向右依次
        :return: result: 根据key值返回对应value,不传key则直接返回所有, 没有对应key则返回None
        """
        with open(self.yaml_path, "r", encoding="utf-8") as f:
            content = f.read()
        yaml_content = yaml.safe_load(content)
        if is_modify:
            return yaml_content
        try:
            for key_name in key_names:
                yaml_content = yaml_content.get(key_name, None)
            return yaml_content
        except Exception as e:
            print(f"get_yml_data error:{e}")
            return None

    def set_yaml_data(self, value, *key_names):
        """
        设置yaml文件中的相关属性
        :param: value:修改后的值
        :param: key_names: 需要修改的yaml文件的key关键字,从左向右依次
        """
        yaml_content = self.get_yml_data(True, key_names)
        print(f'yaml_content:before:{yaml_content}')
        key_name = ''
        for item in list([[item] for item in key_names]):
            key_name += str(item)
        print(f'key_name:{key_name}')
        command = "yaml_content" + key_name + '=' + str(value)
        print(f'command:{command}')
        # exec:将字符串转换成python代码执行
        exec(command)
        print(f'yaml_content:after:{yaml_content}')
        with open(self.yaml_path, mode='w', encoding='utf-8') as f:
            f.write(yaml.safe_dump(yaml_content))


if __name__ == '__main__':
    YAML_PATH = os.path.join(os.path.dirname(__file__), 'config.yaml')
    yamlUtil = YamlUtil(YAML_PATH)
    print(yamlUtil.get_yml_data("test1", "test2-1"))
    print(yamlUtil.get_yml_data("test1", "test2-3", "test3-1"))
    yamlUtil.set_yaml_data(1234, "test1", "test2-1")
    yamlUtil.set_yaml_data(111, "test1", "test2-3", "test3-1")

总结

在我平时日常使用中,ini 文件和 yaml 文件是最常用来配置文件或者测试数据的文件类型了。一般在使用配置文件的时候,会采用 ini 文件,在测试数据上会采用 yaml 文件。同时在大部分的情况下,对于 ini 文件和 yaml 文件主要是以读取数据的操作为主,很少会对文件进行增删改操作。


↙↙↙阅读原文可查看相关链接,并与作者交流