Yaml数据驱动

一、Yaml数据存储文件

    YAML 是一种所有编程语言可用的友好的数据序列化标准,语法和其他高阶语言类似,并且可以简单表达清单、散列表,标量等资料形态.
  • 语法规则
    1.大小写敏感
    2.使用缩进表示层级关系
    3.缩进时不允许使用Tab键,只允许使用空格。
    4.缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  • 支持的数据结构
    1.对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
    2.数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
    3.纯量(scalars):单个的、不可再分的值
  • 对象

    • 值为字符
        data.yaml
         animal: pets
    
        转换为python代码
         {'animal': 'pets'}
    
    • 值为字典
        data.yaml
         animal: {"ke1":"pets","key2":"app"} # python字典
    
        转换为python代码
         {animal: {"ke1":"pets","key2":"app"}} # 嵌套字典结构
    
  • 数组

        data.yaml
         animal: 
           - data1
           - data2
        转换为python代码
         {'animal': ['data1', 'data2']}
    
        data.yaml
         animal: ['data1', 'data2'] # python列表
    
        转换为python代码
         {'animal': ['data1', 'data2']} # 字典嵌套列表
    
  • 纯量:包含:字符串,布尔值,整数,浮点数,Null,日期

    字符串
    data.yaml
     value: "hello"

    转换为python代码
     {"value":"hello"}
    布尔值
    data.yaml
     value1: true
     value2: false

    转换为python代码
     {'value1': True, 'value2': False}
    整数,浮点数
    data.yaml
     value1: 12
     value2: 12.102

    转换为python代码
     {'value1': 12, 'value2': 12.102}
    空(Null)
    data.yaml
     value1: ~ # ~ 表示为空
    转换为python代码
     {'value1': None}
    日期
    data.yaml
     value1: 2017-10-11 15:12:12
    转换为python代码
     {'languages': {'value1': datetime.datetime(2017, 10, 11, 15, 12, 12)}}

二、Python解析yaml文件

  • PyYAML库安装
    PyYAML为python解析yaml的库
    安装:pip3 install -U PyYAML
  • yaml文件内容
    Search_Data:
      search_test_001:
        value: 456
        expect: [4,5,6]
      search_test_002:
        value: "你好"
        expect: {"value":"你好"}
  • 读取yaml文件

    • 方法
        yaml.load(stream, Loader=Loader)
        参数:
            stream:待读取文件对象
    

    ```

    示例:
        import yaml
        with open("../Data/search_page.yaml",'r') as f:
            data = yaml.load(f)
            print(type(data)) # 打印data类型
            print(data) # 打印data返回值
    
    执行结果:
        <class 'dict'>
        {'Search_Data': {
            'search_test_002': {'expect': {'value': '你好'}, 'value': '你好'}, 
            'search_test_001': {'expect': [4, 5, 6], 'value': 456}}}
    

- 写入yaml文件内容
{'Search_Data': {
            'search_test_002': {'expect': {'value': '你好'}, 'value': '你好'}, 
            'search_test_001': {'expect': [4, 5, 6], 'value': 456}}}

- 写yaml文件

  - 方法
  yaml.dump(data,stream,**kwds)
  常用参数:
      data:写入数据类型为字典
      stream:打开文件对象
      encoding='utf-8' # 设置写入编码格式
      allow_unicode=True # 是否允许unicode编码


  示例:不设置编码格式
      import yaml
      data = {'Search_Data': {
                      'search_test_002': {'expect': {'value': '你好'}, 'value': '你好'},
                      'search_test_001': {'expect': [4, 5, 6], 'value': 456}}
      with open("./text.yaml","w") as f: # 在当前目录下生成text.yaml文件,若文件存在直接更新内容
          yaml.dump(data,f)
  执行结果:
      1.当前目录生成text.yaml文件
      2.文件内容:
          Search_Data:
            search_test_001:
              expect: [4, 5, 6]
              value: 456
            search_test_002:
              expect: {value: "\u4F60\u597D"} # 中文出现乱码
              value: "\u4F60\u597D" # 中文出现乱码

  ```python
      示例:设置编码格式
          import yaml
          data = {'Search_Data': {
                          'search_test_002': {'expect': {'value': '你好'}, 'value': '你好'},
                          'search_test_001': {'expect': [4, 5, 6], 'value': 456}}
          with open("./text.yaml","w") as f: # 在当前目录下生成text.yaml文件,若文件存在直接更新内容
              yaml.dump(data,f)
      执行结果:
          1.当前目录生成text.yaml文件
          2.文件内容:
              Search_Data:
                search_test_001:
                  expect: [4, 5, 6]
                  value: 456
                search_test_002:
                  expect: {value: 你好} # 中文未出现乱码
                  value: 你好 # 中文未出现乱码

三、Yaml数据驱动应用

    目标集成Pytest完成测试任务
  • 测试项目
    业务:
        1.进入设置点击搜索按钮
        2.输入搜索内容
        3.点击返回
  • 目录结构
        App_Project # 项目名称
          - Basic # 存储基础设施类
              - __init__.py # 空文件
              - Init_Driver.py # 手机驱动对象初始化
              - Base.py # 方法的二次封装
              - read_data.py #数据解析读取方法
          - Page # 存储封装页面文件
              - __init__.py # 存储页面元素
              - search_page.py # 封装页面元素的操作方法
          - Data # 存储数据文件
              - search_data.yaml(也可以是其他文件比如txt,excel,json,数据库等)
          - Test # 存储测试脚本目录
              - test_search.py # 测试搜索文件
          - pytest.ini # pytest运行配置文件
  • 前置条件
    1.手机驱动对象独立 # 见PO章节代码
    2.方法的二次封装 # 见PO章节代码
    3.完成页面的封装 # 见PO章节代码
  • 待完成任务
    1.编写数据驱动文件search_data.yaml
    2.编写解析yaml文件类/方法
    3.编写测试脚本
  • 编写search_data.yaml
    search_test_001: # 用例编号
      input_text: "你好" # 测试输入数据
    search_test_002:
      input_text: "1234"
    search_test_003:
      input_text: "*&^%"
  • 编写解析yaml方法
    read_data.py

    import yaml,os
    class Read_Data:
        def __init__(self,file_name):
            '''
                使用pytest运行在项目的根目录下运行,即App_Project目录
                期望路径为:项目所在目录/App_Project/Data/file_name
            '''
            self.file_path = os.getcwd() + os.sep + "Data" + os.sep + file_name 
        def return_data(self):
            with open(self.file_path,'r') as f:
                data = yaml.load(f) # 读取文件内容
                return data

        # data:{"search_test_001":{"input_text": "你好"},"search_test_002":{"input_text": "1234"},"search_test_003":{"input_text": "*&^%"}}
  • 测试脚本编写
    test_search.py

    import sys,os
    # 因为需要在项目的根目录下运行,所以需要添加python包搜索路径
    # pytest命令运行路径:App_Project目录下
    # os.getcwd(): App_Project所在目录/App_Project
    sys.path.append(os.getcwd())

    # 导入封装好的页面类
    from Page.search_page import Search_Page
    # 导入独立的手机驱动对象
    from Basic.Init_Driver import init_driver
    from Basic.read_data import Read_Data
    import pytest
    def package_param_data():
        list_data = [] # 存储参数值列表,格式[(用例编号1,输入内容2),(用例编号1,输入内容2)...]
        yaml_data = Read_Data("search_data.yaml").return_data() # 返回yaml文件读取数据
        for i in yaml_data.keys():
            list_data.append((i,yaml_data.get(i).get('input_text'))) # list_data中添加参数值
        return list_data

    class Test_Search:
        '''
            我们希望测试函数运行多次,不希望每运行一次做一次初始化和退出,
            所以使用setup_class,teardown_class,
            测试类内只运行一次初始化和结束动作.
        '''
        def setup_class(self):
            self.driver = init_driver()

        @pytest.mark.parametrize('test_id,input_text',package_param_data()) # 参数传递三组参数,会运行三次
        def test_search(self,test_id,input_text):
            # 示例化页面封装类
            sp = Search_Page(self.driver)
            # 调用操作类
            print("test_id:",test_id)
            sp.input_search_text(input_text)
            # 退出driver对象

        def teardown_class(self):
            self.driver.quit()
  • pytest的配置文件
    pytest.ini

    [pytest]
    addopts = -s  --html=./report.html
    # 测试路径
    testpaths = ./Test
    # 测试文件名
    python_files = test_*.py
    # 测试类名
    python_classes = Test_*
    # 测试的方法名
    python_functions = test_*
  • 项目运行
    1.启动appium 服务:地址 127.0.0.1 端口 4723
    2.启动模拟器
    3.进入项目根目录:App_Project
    4.命令行输入pytest运行测试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值