接口框架项目实战-pytest(五)yaml用例封装

yaml文件规则说明.txt

bash 复制代码
1、yaml 文件一级目录必须包括 name、request、extract、validate
2、在request一级目录下二级目录 必须包括 method、url
3、如果需要做接口关联的话,必须使用一级关键字:extract
get 请求 params 传参
post 请求
 json传参,通过json关键字
 表单传参 通过data关键字
 文件格式 通过files关键字
如 json提取
  extract:
      access_token: access_token
  正则表达提取
    extract:
      access_token: '"access_token":"(.*?)"'
当需要使用随机参数时 可以调用common_util.py 中get_random_value 方法
如
name: "ms${get_random_value(100,200)}"
     

common_util.py

bash 复制代码
import random


class CommonUtil:
    def get_random_value(self,min,max):
        return random.randint(int(min),int(max))

requests_util.py

bash 复制代码
import json
import re

import jsonpath as jsonpath
import requests

from pytestdemo.common.common_util import CommonUtil
from pytestdemo.common.yaml_util import read_config_file, read_extract_file, write_extract_file


class RequestsUtil:
    base_url=""
    def __init__(self,base,base_url):
        self.base_url=read_config_file(base,base_url)
    session=requests.Session()
    def replace_value(self,data):
        if data and isinstance(data,dict):
            str=json.dumps(data)
        else:
            str=data
        # 将变量替换成值
        for a in range(1,str.count("{{")+1):
            if "{{" in str and "}}" in str:
                print(str)
                start_index=str.index("{{")
                end_index = str.index("}}")
                print(start_index,end_index)
                old_value=str[start_index:end_index+2]
                new_value=read_extract_file(old_value[2:-2])
                str=str.replace(old_value,new_value)
        if data and isinstance(data,dict):
            data=json.loads(str)
        else:
            data=str
        return data
    def replace_load(self,data):
        if data and isinstance(data,dict):
            str_value=json.dumps(data)
        else:
            str_value=data
        # 将变量替换成值
        for a in range(1,str_value.count("${")+1):
            if "${" in str_value and "}" in str_value:
                start_index=str_value.index("${")
                end_index = str_value.index("}")
                old_value=str_value[start_index:end_index+1]
                fun_name=old_value[old_value.index("${")+2:old_value.index("(")]
                params=old_value[old_value.index("(")+1:old_value.index(")")]
                # 反射获取
                new_value=getattr(CommonUtil(),fun_name)(*params.split(","))
                str_value=str_value.replace(old_value,str(new_value))
        if data and isinstance(data,dict):
            data=json.loads(str_value)
        else:
            data=str_value
        return data
    def analysis_yml_send_reqeust(self,data):
        data_key=  dict(data).keys()
        print(data_key)
        if 'name' in data_key  and 'request' in data_key and 'validate' in data_key:
                # and 'extract' in data_key

            request_key=dict(data["request"]).keys()
            if 'method' in request_key and 'url' in request_key:
                headers=None
                method=data["request"]["method"]
                del data["request"]["method"]
                url=data["request"]["url"]
                del data["request"]["url"]
                if jsonpath.jsonpath(data,"$..headers") :
                    headers=data["request"]["headers"]
                    del data["request"]["headers"]
                files=None
                if jsonpath.jsonpath(data,"$..files"):
                    files=data["request"]["files"]
                    for key,value in dict(data["request"]["files"]).items():
                        files[key]=open(value,"rb")

                    del data["request"]["files"]
                print(data["request"])
                res = self.send_request(method=method
                                        , url=url
                                        , headers=headers
                                        ,files=files
                                        , **data["request"]
                                        )
                return_json=res.json()
                return_text=res.text
                print(res.text)
                if 'extract' in data_key:
                    for key,value in dict(data["extract"]).items():
                        # 正则表达式
                        extract_data=None
                        if "(.*?)" in value or "(.+?)" in value:
                           search_value=re.search(value,return_text)
                           if search_value:
                               extract_data=search_value.group(1)

                        else:
                            extract_data=return_json[value]
                        if search_value:
                            write_extract_file({key:extract_data})

            else:
                print("在request一级目录下二级目录 必须包括 method、url")
        else:
            print("1、yaml 文件一级目录必须包括 name、request、extract、validate")

    def send_request(self,method,url,headers=None,**kwargs):
        method=str(method).lower()
        url=self.base_url+self.replace_value(url)
        for key,value in kwargs.items():
            if key in ["params","data","json"]:
                kwargs[key]=self.replace_value(value)
                kwargs[key] = self.replace_load(value)

        res=RequestsUtil.session.request(method=method,url=url,headers=headers,**kwargs);
        return  res

yaml_util.py

bash 复制代码
import os

import yaml



def get_path():
    return os.path.abspath(os.getcwd().split("common")[0])
def read_config_file(one_node,two_node):
    with open(f'{get_path()}/common/config.yml',encoding="utf-8") as f:
        value=yaml.load(f,yaml.FullLoader)
        # print(value[one_node][two_node])
        return value[one_node][two_node]
def read_extract_file(node_name):
    with open(f'{get_path()}/common/extract.yml',encoding="utf-8") as f:
        value=yaml.load(f,yaml.FullLoader)
        return value[node_name]
def write_extract_file(data):
    with open(f'{get_path()}/common/extract.yml',encoding="utf-8",mode="a") as f:
        yaml.dump(data,f,allow_unicode=True)

def clean_extract_file():
    with open(f'{get_path()}/common/extract.yml',encoding="utf-8",mode="w") as f:
       f.truncate()
def read_testcase_yaml(file_path):
    print(f'{get_path()}{file_path}')
    with open(f'{get_path()}{file_path}',encoding="utf-8") as f:
        value = yaml.load(f, yaml.FullLoader)
        return value
if __name__ == '__main__':
    # print (read_config_file("base","base_php_url"))
    print(read_testcase_yaml("\\testcases\\get_token.yml"))

config.yml

bash 复制代码
base:
    base_php_url: http://47.107.116.139
    base_wx_url: https://api.weixin.qq.com

conftest.py

bash 复制代码
import pytest
from pytestdemo.common.yaml_util import clean_extract_file

@pytest.fixture(scope="session",autouse=True)
def clean_extract():
    clean_extract_file()

test_demo4.py

bash 复制代码
import random

import pytest

from pytestdemo.common.requests_util import RequestsUtil
from pytestdemo.common.yaml_util import write_extract_file, read_testcase_yaml


class Test4Api:
    access_token=""
    @pytest.mark.parametrize("data",read_testcase_yaml("/testcases/get_token.yml"))
    def test_get_token(self,data):
        RequestsUtil("base","base_wx_url").analysis_yml_send_reqeust(data)
    @pytest.mark.parametrize("data", read_testcase_yaml("/testcases/get_tags.yaml"))
    def test_get_tags(self,data):
        RequestsUtil("base", "base_wx_url").analysis_yml_send_reqeust(data)
    @pytest.mark.parametrize("data", read_testcase_yaml("/testcases/update_tag.yml"))
    def test_update_tag(self,data):
        RequestsUtil("base", "base_wx_url").analysis_yml_send_reqeust(data)
 
    @pytest.mark.parametrize("data", read_testcase_yaml("/testcases/uploadimg.yml"))
    def test_uploadimg(self,data):
        RequestsUtil("base", "base_wx_url").analysis_yml_send_reqeust(data)

get_token.yml

bash 复制代码
- name: 获取鉴权码
  request:
    method: get
    url: /cgi-bin/token
    params:
      grant_type: client_credential
      appid: xxx
      secret: xxx
  extract:
      access_token: '"access_token":"(.*?)"'
  validate:
      - eq:
          - status_code
          - 200

get_tags.yaml

bash 复制代码
- name: 获取标签
  request:
    method: get
    url: /cgi-bin/tags/get?access_token={{access_token}}
  validate:
      - eq:
          - status_code
          - 200

update_tag.yml

bash 复制代码
- name: 修改标签
  request:
    method: post
    url: /cgi-bin/tags/update?access_token={{access_token}}
    json:
      tag:
         id: 23475
         name: ms1213
         keyss: "{{access_token}}"
  validate:
      - eq:
          - status_code
          - 200

uploadimg.yml

bash 复制代码
- name: 修改标签
  request:
    method: post
    url: /cgi-bin/tags/update?access_token={{access_token}}
    json:
      tag:
         id: 23794
         name: "ms${get_random_value(100,200)}"
  validate:
      - eq:
          - status_code
          - 200

uploadimg.yml

bash 复制代码
- name: 修改标签
  request:
    method: post
    url: /cgi-bin/media/uploadimg?access_token={{access_token}}
    files:
      media: C:\\Users\\Administrator\\Desktop\\1.jpg
  validate:
      - eq:
          - status_code
          - 200

思考问题登录失败 之后的用例需要停止执行

相关推荐
西柚小萌新1 小时前
【Python爬虫基础篇】--4.Selenium入门详细教程
爬虫·python·selenium
橘猫云计算机设计1 小时前
springboot基于hadoop的酷狗音乐爬虫大数据分析可视化系统(源码+lw+部署文档+讲解),源码可白嫖!
数据库·hadoop·spring boot·爬虫·python·数据分析·毕业设计
YOULANSHENGMENG1 小时前
linux 下python 调用c++的动态库的方法
c++·python
SsummerC2 小时前
【leetcode100】零钱兑换Ⅱ
数据结构·python·算法·leetcode·动态规划
夸克App2 小时前
实现营销投放全流程自动化 超级汇川推出信息流智能投放产品“AI智投“
运维·人工智能·自动化
Rainbond云原生2 小时前
83k Star!n8n 让 AI 驱动的工作流自动化触手可及
运维·人工智能·自动化
YONG823_API2 小时前
深度探究获取淘宝商品数据的途径|API接口|批量自动化采集商品数据
java·前端·自动化
木觞清2 小时前
深度对比评测:n8n vs Coze(扣子) vs Dify - 自动化工作流工具全解析
运维·自动化
一眼青苔2 小时前
切割PDF使用python,库PyPDF2
服务器·python·pdf
电商数据girl2 小时前
产品经理对于电商接口的梳理||电商接口文档梳理与接入
大数据·数据库·python·自动化·产品经理