一、yaml基本语法
1.1 yaml格式
- 文件格式必须以 .yaml 格式为后缀
- 键值对使用冒号结构表示key: value,冒号后面要加一个空格
- YAML是一种数据类型,它可以和json之间灵活的切换,支持注释、换行、字符串。
- YAML 是专门用来写配置文件的语言,非常简洁和强大,远比 JSON 格式方便。
1.2 yaml的基本语法
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用tab,只允许使用空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
- #表示注释
1.3 yaml的数据类型
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
- 纯量(scalars):单个的、不可再分的值
a.YAML 对象(object):
键值对使用冒号结构表示 key: value,冒号后面要加一个空格。
# 对象(object)格式
request:
method: post
url: https://127.0.0.1:8080/api/login
headers:
Content - type: application/json
datas:
username: test
password: test123456
validate: none
b.YAML 数组(array):
以 - 开头的行表示构成一个数组
# 数组(array)
companies:
-
id: 1
name: company1
price: 200W
-
id: 2
name: company2
price: 500W
c.YAML 纯量(scalar):
纯量是最基本的,不可再分的值,包括:字符串、布尔值、整数、浮点数、Null、日期、时间
# 字符串:
string:
- 你好
- 'hello word' # 可以用双引号或者单引号包裹特殊字符
- newline
- newline2
# 布尔值
boolean:
- TRUE
- FALSE
# 整数
int:
- 123456
# 浮点数
float:
- 3.14159
- 23.325
# Null#(使用~表示null)
params: ~
# 日期(日期必须使用ISO 8601格式,即yyyy-MM-dd)
- 2022-07-08
# 时间 (时间使用ISO8601格式,时间和日期之间使用T连接,最后使用+代表时区)
- 2022-07-08T10:06:31+08:00
1.4 yaml的使用
安装 yaml 模块:
pip install pyyaml
导包:
import yaml
具体方法:
yaml.load(f)
作用是将yaml文档转化为python对象
yaml.load_all(f)
返回yaml文件中所有的yaml文档的对象生成一个迭代器,再使用for打印出来
yaml.dump(c,f)
将一个python对象生成yaml文档,存放再f中
yaml.dump_all(c,f)
将多个python对象生成yaml文档,存放在f中
yaml文件小demo:data.yaml
#创建data.yml
-
name: 张飞
age: 15
score:
- English: 90
- Chinese: 92
- Math: 95
-
name: 孙策
age: 19
score:
- English: 85
- Chinese: 98
- Math: 69
二、封装读取yaml的方法
import yaml
class yamlUtil(object):
def __init__(self, yaml_file):
'''
通过init把文件传入到这个类中
:param yaml_file
'''
self.yaml_file = yaml_file
def read_yaml(self):
'''
读取yaml,将yaml反序列化,就是把yaml格式转换为dict格式
'''
with open(self.yaml_file, encoding="utf-8") as f:
value = yaml.load(stream=f, Loader=yaml.FullLoader) # 文件流,加载方式
print(value)
return value
if __name__ == '__main__':
yamlUtil(r"D:\ApiTest3\PyYaml_cases\data.yaml").read_yaml()
三、通过@pytest.mark.parametrize()实现yaml的数据驱动
Import_yaml.py
import pytest
import os
from PyYaml_cases import test_yaml
class Test_yaml(object):
file = os.getcwd() + "./data.yaml"
print(file)
@pytest.mark.parametrize("args", test_yaml.yamlUtil(os.getcwd() + './data.yaml').read_yaml())
def test_yaml(self, args):
print(args)
name = args['name']
age = args['age']
print(name)
print(age)
输出:
============================= test session starts =============================
collecting ... collected 2 items
Import_yaml.py::Test_yaml::test_yaml[args0] PASSED [ 50%]{'name': '张飞', 'age': 15, 'score': [{'English': 90}, {'Chinese': 92}, {'Math': 95}]}
张飞
15
Import_yaml.py::Test_yaml::test_yaml[args1] PASSED [100%]{'name': '孙策', 'age': 19, 'score': [{'English': 85}, {'Chinese': 98}, {'Math': 69}]}
孙策
19
============================== 2 passed in 0.08s ==============================
Process finished with exit code 0
四、YAML代码案例
- 案例:创建用例文件以及数据文件来完成数据驱动的测试案例,创建一个文件夹testdata,在这个文件夹下创建my_data.yaml和my_test.py文件,如下图所示:
1.yaml的数据类型是列表
案例一:
my_data.yaml
# my_data.yaml
-
- 1
- 2
-
- 20
- 30
my_test.py
# my_test.py
import pytest
import yaml
@pytest.mark.parametrize("a, b", yaml.safe_load(open("my_data.yaml", encoding="utf-8")))
def test_foo(a, b):
print(f"a+b = {a+b}")
运行结果:
============================= test session starts =============================
collecting ... collected 2 items
my_test.py::test_foo[1-2] PASSED [ 50%]a+b = 3
my_test.py::test_foo[20-30] PASSED [100%]a+b = 50
============================== 2 passed in 0.11s ==============================
Process finished with exit code 0
案例二:
my_data1.yaml
# my_data1.yaml
-
dev: 127.0.0.1
my_test1.py
# my_test1.py
import pytest
import yaml
class TestDemo:
def test_get_data(self):
data = yaml.safe_load(open("my_data1.yaml", encoding="utf-8"))
print(type(data))
@pytest.mark.parametrize("env", yaml.safe_load(open("my_data1.yaml", encoding="utf-8")))
def test_demo(self, env):
if "test" in env:
print("这是测试环境")
print("IP是:", env['test'])
elif 'dev' in env:
print("这是开发环境:")
print("IP是:", env['dev'])
运行结果:
============================= test session starts =============================
collecting ... collected 2 items
my_test1.py::TestDemo::test_get_data PASSED [ 50%]<class 'list'>
my_test1.py::TestDemo::test_demo[env0] PASSED [100%]这是开发环境:
IP是: 127.0.0.1
============================== 2 passed in 0.06s ==============================
案例三:
my_data2.yaml
# my_data2.yaml
-
- 10
- 20
-
- 30
- 6
my_test2.py
# my_test2.py
import pytest
import yaml
class TestData:
# @pytest.mark.parametrize("a,b",[(10,20),(10,30)])
# 元祖
# @pytest.mark.parametrize(("a","b"), [(10, 20), (10, 30)])
# #列表
# @pytest.mark.parametrize(["a", "b"], [(10, 20), (10, 30)])
@pytest.mark.parametrize(["a", "b"], yaml.safe_load(open('my_data2.yaml')))
def test_data(self, a, b):
print(f"a+b = {a + b}")
运行结果:
============================= test session starts =============================
collecting ... collected 2 items
my_test2.py::TestData::test_data[10-20] PASSED [ 50%]a+b = 30
my_test2.py::TestData::test_data[30-6] PASSED [100%]a+b = 36
============================== 2 passed in 0.06s ==============================
Process finished with exit code 0
案例四:
my_data3.yaml
# my_data3.yaml
-
- 10
- 10
- 20
-
- 30
- 6
- 36
my_test3.py
# my_test3.py
import pytest
import yaml
def my_add(x, y):
result = x + y
return result
def test_get_json():
with open("my_data3.yaml", 'r', encoding='utf-8') as file:
data = yaml.safe_load(file.read())
data1 = []
for i in data:
data1.append(i)
print(data1)
return data1
class TestWithJson:
@pytest.mark.parametrize("x, y, expected", test_get_json())
def test_add(self, x, y, expected):
value = my_add(x, y)
assert value == int(expected)
运行结果:
============================= test session starts =============================
collecting ... collected 2 items
my_test3.py::TestWithJson::test_add[10-10-20] PASSED [ 50%]
my_test3.py::TestWithJson::test_add[30-6-36] PASSED [100%]
============================== 2 passed in 0.18s ==============================
Process finished with exit code 0
2.yaml的数据类型是字典
my_data4.yaml
my_data4.yaml
info:
"name": "chengzi"
"age": 18
my_test4.py
# my_test4.py
import pytest
import yaml
def get_data():
data = yaml.safe_load(open('my_data4.yaml', encoding='utf-8'))
name = data['info']['name']
age = data['info']['age']
return name, age
# 这个用例是为了打印数据,可以忽略
def test_get_data():
data = yaml.safe_load(open('my_data4.yaml', encoding='utf-8'))
name = data['info']['name']
age = data['info']['age']
print(name)
print(age)
print(data)
print(type(data))
@pytest.mark.parametrize("name, age",[get_data()])
def test_info(name,age):
print(f'姓名是:{name},年龄是:{age}')
运行结果:
============================= test session starts =============================
collecting ... collected 2 items
my_test4.py::test_get_data PASSED [ 50%]chengzi
18
{'info': {'name': 'chengzi', 'age': 18}}
<class 'dict'>
my_test4.py::test_info[chengzi-18] PASSED [100%]姓名是:chengzi,年龄是:18
============================== 2 passed in 0.07s ==============================
Process finished with exit code 0