Pytest测试框架(六)Yaml技术

1.基本语法

大小写敏感
使用缩进表示层级关系
缩进不允许使用tab,只允许空格
缩进的空格数不重要,只要相同层级的元素左对齐即可
# 表示注释,从它开始到行尾都被忽略

2.数据类型

YAML 支持以下几种数据类型:
对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
纯量(scalars):单个的、不可再分的值

3.YAML 对象

对象键值对使用冒号结构表示 key: value,冒号后面要加一个空格。
也可以使用 key:{key1: value1, key2: value2, …}。
还可以使用缩进表示层级关系;

key: 
    child-key: value
    child-key2: value2

较为复杂的对象格式,可以使用问号加一个空格代表一个复杂的 key,配合一个冒号加一个空格代表一个 value:

?  
    - complexkey1
    - complexkey2
:
    - complexvalue1
    - complexvalue2

意思即对象的属性是一个数组 [complexkey1,complexkey2],对应的值也是一个数组 [complexvalue1,complexvalue2]

4.YAML 数组或列表

以 - 开头的行表示构成一个数组:

# 下面格式读到Python里会是个list
- A
- B
- C

数据结构的子成员是一个数组,则可以在该项下面缩进一个空格。

-
 - A
 - B
 - C

一个相对复杂的例子:

companies:
    -
        id: 1
        name: company1
        price: 200W
    -
        id: 2
        name: company2
        price: 500W

意思是 companies 属性是一个数组,每一个数组元素又是由 id、name、price 三个属性构成。

5.yaml转字典

# 下面格式读到Python里会是个dict
name: 灰蓝
age: 0
job: Tester

6.复合结构

数组和对象(字典和列表)可以构成复合结构

languages:
  - Ruby
  - Perl
  - Python 
websites:
  YAML: yaml.org 
  Ruby: ruby-lang.org 
  Python: python.org 
  Perl: use.perl.org

输出:

{ 
  languages: [ 'Ruby', 'Perl', 'Python'],
  websites: {
    YAML: 'yaml.org',
    Ruby: 'ruby-lang.org',
    Python: 'python.org',
    Perl: 'use.perl.org' 
  } 
}

7.基本类型

yaml中有以下基本类型:

  • 字符串
  • 布尔值
  • 整数
  • 浮点数
  • Null
  • 时间
  • 日期
boolean: 
    - TRUE  #true,True都可以
    - FALSE  #false,False都可以
float:
    - 3.14
    - 6.8523015e+5  #可以使用科学计数法
int:
    - 123
    - 0b1010_0111_0100_1010_1110    #二进制表示
null:
    nodeName: 'node'
    parent: ~  #使用~表示null
string:
    - 哈哈
    - 'Hello world'  #可以使用双引号或者单引号包裹特殊字符
    - newline
      newline2    #字符串可以拆成多行,每一行会被转化成一个空格
date:
    - 2018-02-17    #日期必须使用ISO 8601格式,即yyyy-MM-dd
datetime: 
    -  2018-02-17T15:02:31+08:00    #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区

如果字符串没有空格或特殊字符,不需要加引号,但如果其中有空格或特殊字符,则需要加引号了

str: 灰蓝
str1: "Hello World"
str2: "Hello\nWorld"

输出:

{'str2': 'Hello\nWorld', 'str1': 'Hello World', 'str': u'\u7070\u84dd'}

这里要注意单引号和双引号的区别,单引号中的特殊字符转到Python会被转义,也就是到最后是原样输出了,双引号不会被Python转义,到最后是输出了特殊字符;

str1: 'Hello\nWorld'
str2: "Hello\nWorld"
# -*- coding: utf-8 -*-
import yaml

y = yaml.load(file('test.yaml', 'r'))
print y['str1']
print y['str2']

输出:

Hello\nWorld
Hello
World

8.引用

&* 用于引用

name: &name 灰蓝
tester: *name

这个相当于一下脚本:

name: 灰蓝
tester: 灰蓝

输出:

{'name': u'\u7070\u84dd', 'tester': u'\u7070\u84dd'}

9. 强制转换

yaml是可以进行强制转换的,用 !! 实现,如下:

str: !!str 3.14
int: !!int "123"

输出:

{'int': 123, 'str': '3.14'}

明显能够看出123被强转成了int类型,而float型的3.14则被强转成了str型。另外PyYaml还支持转换成Python/object类型

10. 分段

在同一个yaml文件中,可以用 --- 来分段,这样可以将多个文档写在一个文件中

---
name: James
age: 20
---
name: Lily
age: 19

这时候我们就得用到我们的 load_all() 方法出场了,load_all() 方法会生成一个迭代器,可以用for输出出来:

# -*- coding: utf-8 -*-
import yaml

ys = yaml.load_all(file('test.yaml', 'r'))
for y in ys:
    print y

输出:

{'age': 20, 'name': 'James'}
{'age': 19, 'name': 'Lily'}

对应的也有 dump_all() 方法,一个意思,就是将多个段输出到一个文件中,

# -*- coding: utf-8 -*-
import yaml

obj1 = {"name": "James", "age": 20}
obj2 = ["Lily", 19]

with open('test.yaml', 'w') as f:
    yaml.dump_all([obj1, obj2], f)

打开test.yaml看看:

{age: 20, name: James}
--- [Lily, 19]

dump()dump_all() 方法可以传入列表,也可以传入一个可序列化生成器,如 range(10), 如下:

# -*- coding: utf-8 -*-
import yaml
fo = open('../config/test.yaml','w',encoding='utf-8')
yaml.dump(range(10),fo)

输出:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

dumpdump_all() 的时候还可以配一堆参数

二、Yaml操作

1、yaml使用场景

  • 配置文件
  • 测试用例

2.yaml语法

  • 字典
  • 列表
  • 嵌套
  • 注释
  • & * 变量操作
  • 多用例
  • 空格与颜色变化
- #test4
  url: /api/mgr/loginReq
  method: post
  detail: 不传账号,不传密码
  data:
    username: "" #如果不填  None
    password: ""
  check:
    retcode: 1
    reason: 用户或者密码错误

3.yaml里引用yaml文件

问题并没有要求Python解决方案,但下面是一个使用PyYAML…

PyYAML允许您附加自定义构造函数(如!include )到YAML加载程序

基于类的解决方案

这里有一个基于类的解决方案,它避免了我最初响应的全局根变量。
使用元类注册自定义构造函数:

import yaml
import os.path

class Loader(yaml.Loader):

      def __init__(self, stream):
            self._root = os.path.split(stream.name)[0]
            super(Loader, self).__init__(stream)

      def include(self, node):
            filename =os.path.join(self._root,self.construct scalar(node))

            with open(filename, 'r') as f:
            return yaml.load(f, Loader)


Loader.add_constructor('!include', Loader.include)

例如:
a.yaml

a:1
b:
    - 2
    - 3

c: !include bar.yaml

b.yaml

-10
- [100, 200, 300]

现在可以使用以下方法加载文件:

with open('a.yaml', 'r') as f:
data = yaml.load(f, Loader)
print(data)

 {'a': 1, 'b': [2, 3], 'c': [10, [100,200, 300]]}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凡晨丹心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值