Pytest+Yaml+Allure接口自动化框架集成

9 阅读5分钟

Pytest+Yaml+Allure接口自动化框架集成

1.框架介绍

2.YAML 用例编写规范

3.YAML用例数据读取

4.核心执行器用例执行

1.框架介绍

框架的内容

关键字驱动框架

1.examples用例文件夹

yaml/excel用例(选择一种即可)

2.HAT框架代码

parse 读取yaml/excel用例数据

core 执行用例(核心执行器执行用例--本质pytest)

keywords 项目封装的操作

utils 工具类

extend 扩展的组件

context 上下文管理 管理会话(一次会话还是多次会话)

main程序入口

requirements.txt作用:

拿到这个项目目前安装了哪些库,导出来库 pip freeze >requirements.txt

给项目给别人,跑项目 txt文件 pip install -r requirements.txt -i 镜像

2.yaml用例编写规范

用例怎么写?

yaml用例--yaml规则

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许空格
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • '#' 表示注释
  • 列表
  • :字典 :后面需要有个空格

3.读取yaml文件数据:

1.安装pyyaml库

pip install pyyaml -i 镜像

2.读取yaml数据

常识:

  • ./ 同级目录

  • ../上一级目录

  • ../../上上级目录

  • r''是为了防止转义,比如\n \t 有自己的意思,比如空格,比如换行

4.核心执行器用例执行

目标:

如果已经拿到了yaml的数据,怎么执行登录的接口?

回答:

核心执行器执行,本质就是pytest

要安装pytest

pip install pytest==7.3.1 -i 镜像

拿到数据,调度执行yaml用例

1.拿到yaml数据后需要传给相应的接口

parse/ReadYamlCase文件

import yaml
import os
import os
print(os.getcwd())  

# 获取当前文件所在文件夹的目录
current_dir = os.path.dirname(os.path.abspath(__file__))
# 获取要读取的yaml文件的完整路径
yaml_path = os.path.join(current_dir, '../../examples/api-cases-yaml/test.yaml')




def readYaml(yaml_path):
    case_info=[]
    with open(yaml_path, 'r',encoding='utf-8') as f:
        data = yaml.load(f, Loader=yaml.FullLoader)
        print("yaml文件数据:", data)
        case_info.append(data)
    return case_info



if __name__=="__main__":
    readYaml(yaml_path)

在core里面的TestRunner.py中:(核心执行器--本质是pytest)

import os
import sys
import pytest


current_directory = os.path.dirname(os.path.abspath(__file__))
hat_dir = os.path.dirname(current_directory)
sys.path.append(hat_dir)

from parse.YamlCaseParser import readYaml


print(os.getcwd())
print(current_directory)

file_path = os.path.abspath(os.path.join(current_directory, '../../examples/api-cases-yaml/test.yaml'))
print(file_path)
class TestRunner2:
    data = readYaml(file_path)
    # print(data)
    @pytest.mark.parametrize('caseinfo',data)#把data的数据拿过来,放到caseinfo里面,一定是一个列表,然后通过parametrize会把列表去掉,变成一个裸字典

2.执行登录接口

  1. 在main.py中设置执行的参数以及需要执行的文件路径

  2. 执行 发送请求POST接口,需要四要素(url,请求方式,接口参数,响应结果)

怎么在yaml数据中找到我想要的信息:

yaml数据

用例步骤:     #具体要测试的接口内容
- 发送登陆接口:
    操作类型: 发送请求POST  #一定要跟Keywords发请求的函数名一致
    请求地址: "http://shop-xo.hctestedu.com"  #加不加index.php对于这个商城项目接口都可以  如果加可以在后面加个/index.php
    URL参数:
      s: /api/user/login
      application: app
      application_client_type: weixin
    请求数据:
      accounts: "youyi"
      pwd: "123456"
      type: "username"

1.整个是个字典,我想取字典里的这个内容用例步骤 所以 step_info=caseinfo.get("用例步骤",none)

{'发送登陆接口': {'操作类型': '发送请求POST', '请求地址': 'http://shop-xo.hctestedu.com', 'URL参数': {'s': '/api/user/login', 'application': 'app', 'application_client_type': 'weixin'}, '请求数据': {'accounts': 'youyi', 'pwd': '123456', 'type': 'username'}}}

2.要取到发送的是什么接口: step_name=step_info.key()

要取到接口的所有信息: step_value=step_info.values()

dict_value{'操作类型': '发送请求POST', '请求地址': 'http://shop-xo.hctestedu.com', 'URL参数': {'s': '/api/user/login', 'application': 'app', 'application_client_type': 'weixin'}, '请求数据': {'accounts': 'youyi', 'pwd': '123456', 'type': 'username'}}

目前取到的只是字典的键对象和值对象,我需要把他转成列表,然后再取到列表中的元素

所以是step_name = list(step_info.key())[0]

step_value = list(step.values())[0]

3.实例化对象

4.找KeyWords类中是否有发送请求POST方法

若能找到-传入相应参数 找不到-抛异常

代码如下:

import os
import sys
import pytest
import requests


current_directory = os.path.dirname(os.path.abspath(__file__))
hat_dir = os.path.dirname(current_directory)
sys.path.append(hat_dir)

from parse.YamlCaseParser import readYaml
from keywords.api_keywords import Keywords

# print(os.getcwd())
# print(current_directory)

file_path = os.path.abspath(os.path.join(current_directory, '../../examples/api-cases-yaml/login.yaml'))
# print(file_path)

class TestRunner2:
    data = readYaml(file_path)
    # print(data)
    @pytest.mark.parametrize('caseinfo',data)#把data的数据拿过来,放到caseinfo里面,一定是一个列表,然后通过parametrize会把列表去掉,变成一个裸字典
    def test_case_execute(self,caseinfo):
        keyword = Keywords(requests)
        # 我不需要所有的数据
        # print(caseinfo)
        # 输出和测试报告有关的数据
        base_info=caseinfo.get(('基础配置'),{})
        print("base_info",base_info)
        # 输出和测试用例有关的数据
        steps = caseinfo.get('用例步骤', None)
        # print("steps",steps)
        # 这个steps是一个列表,这个列表中嵌套了字典,那么我想拿其中的字典,就要用循环,目前虽然只有一个字典,但是实际工作中可能会有很多不用的接口,一个接口对应一个字典
        for step in steps:
            print("拿到用例步骤数据",step)
            # 开始取到的是字典的键对象,是dict_key[],需要转化成列表
            step_name = list(step.keys())[0]
            # 开始取到的是字典的值对象,是dict_values[],需要转化成列表
            step_value = list(step.values())[0]
            key =step_value['操作类型']
            try:
                # 在KeyWords中找发送请求POST
                keyfunc = keyword.__getattribute__(key)
            except Exception as e:
                print("操作类型不存在",e)
                raise
            # keyfunc就是发送请求POST() 调用函数,直接把参数传入函数就可以
            keyfunc(**step_value)