pytest测试框架使用基础08 通过Yaml实现数据驱动

一、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
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值