当前位置: 首页 > article >正文

【接口自动化连载】使用yaml配置文件自动生成接口case

直接上干货撸代码,有一些是通用的工具类代码,一次性封装永久使用,期待大家的关注,一起加油!!!

配置文件

根据不同的业务需求进行配置,例如Goods服务、Order服务分开配置,每个服务下配置接口信息,每个接口文件里配置各种case。
/conf/GooodsApi/get_shop_info.yaml

# 公共参数
case_common:
  allureEpic: 商品接口
  allureFeature: 店铺信息
  allureStory: 店铺信息

get_user_info_01:
    host: https://goodsapi.e.weibo.com
    url: /mp/shop/getShopInfo
    method: GET
    detail: 获取商家店铺信息
    headers:
#      Content-Type: multipart/form-data;
      # 这里cookie的值,写的是存入缓存的名称
#      cookie: $cache{login_cookie}
    # 请求的数据,是 params 还是 json、或者file、data
    requestType: params
    # 是否执行,空或者 true 都会执行
    is_run:
    data:
      {"shop_id": xxxx}
      # 是否有依赖业务,为空或者false则表示没有
    dependence_case: False
        # 依赖的数据
    dependence_case_data:
    assert:
      # 断言接口状态码
      errorCode:
        jsonpath: $.code
        type: ==
        value: 0
        AssertType:
    sql:

通用工具类

文件操作

/utils/file_operate.py

import os


def get_root_path():
	"""获取(项目)根目录"""
	return os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 


def ensure_path_sep(path):
	"""兼容windows和Linux不同环境的操作系统路径"""
	if '/' in path:
		path = os.sep.join(path.split('/'))
	if '\\' in path:
		path = os.sep.join(path.split('\\'))
	return get_root_path() + path


def get_all_yaml_files(file_path, yaml_data_switch=False):
	"""获取配置的yaml文件路径"""
	file_name = []
	for root, dir, files in os.walk(file_path):
		for _file_path in files:
			path = os.path.join(root, _file_path)
			if yaml_data_switch:
				if 'yaml' in path or '.yml' in path:
					file_name.append(path)
				file_name.append(path)
		return file_name

操作yaml

/utils/yaml_control.py

Class YamlControl:
	def __init__(self, file_str):
		self.file_str = file_str
	
	def file_is_exists(self, filepath):
		if os.path.exists(filepath):
			return True
		return False
	
	def read_yaml_data(self):
		"""获取yaml文件数据"""
		if self.file_is_exists(self.file_str):
			data = open(self.file_str, "r", encoding="UTF-8")
			yaml_data = yaml.load(data, Loader = yaml.FullLoader)
		else:
			raise FileNotFoundError("文件路径不存在")
		return yaml_data
	
	def save_yaml_data(self, file_path, data):
		if self.file_is_exists(file_path):
			with open(file_path, 'w') as file:
				yaml.safe_dump(data, file, default_flow_style=False)
		else:
			raise FileNotFoundError("文件路径不存在")

自动生成用例代码

/utils/case_automatic_genration.py

import os
from utils.read_file_tools import get_all_yaml_files, ensure_path_sep
from utils.yaml_control import YamlControl
from utils.test_case import write_testcase_file


class TestCaseAutomaticGeneration:
    def __init__(self):
        self.yaml_case_data = None
        self.file_path = None
    
    @property
    def allure_epic(self):
        _allure_epic = self.yaml_case_data.get("case_common").get("allureEpic")
        assert _allure_epic is not None, (
                "用例中 allureEpic 为必填项,请检查用例内容, 用例路径:'%s'" % self.file_path
        )
        return _allure_epic
    
    @property
    def allure_feature(self):
        _allure_feature = self.yaml_case_data.get("case_common").get("allureFeature")
        assert _allure_feature is not None, (
                "用例中 allureFeature 为必填项,请检查用例内容, 用例路径:'%s'" % self.file_path
        )
        return _allure_feature
    
    @property
    def allure_story(self):
        _allure_story = self.yaml_case_data.get("case_common").get("allureStory")
        assert _allure_story is not None, (
                "用例中 allureStory 为必填项,请检查用例内容, 用例路径:'%s'" % self.file_path
        )
        return _allure_story
    @property
    def case_data_path(self):
        """返回 yaml 用例文件路径"""
        return ensure_path_sep("/conf")

    @property
    def gen_file_name(self):
        """生成文件名 将.yaml替换成.py"""
        # 例 /get_shop_info.yaml——>/get_shop_info.py
        # 获取配置文件相对路径
        l = len(self.case_data_path)
        yaml_path = self.file_path[l:]
        file_name = None
        if '.yaml' in yaml_path:
            file_name = yaml_path.replace('.yaml', '.py')
        elif '.yml' in yaml_path:
            file_name = yaml_path.replace('.yml', '.py')
        return file_name

    @property
    def get_test_class_title(self):
        """自动生成类名"""
        # 例 get_shop_info——>GetShopInfo
        _file_name = os.path.split(self.gen_file_name)[1][:-3]
        _name = _file_name.split("_")
        _name_len = len(_name)
        for i in range(_name_len):
            _name[i] = _name[i].capitalize()
        _class_name = "".join(_name)
        return _class_name
    
    @property
    def get_func_title(self):
        """自动生成方法名"""
        return os.path.split(self.gen_file_name)[1][:-3]
    
    @property
    def spilt_path(self):
        # 使用"/"分割 获取文件名称
        path = self.gen_file_name.split(os.sep)
        path[-1] = path[-1].replace(path[-1], "test_" + path[-1])
        return path
    
    @property
    def get_case_path(self):
        """生成测试用例目录"""
        # 相对路径 test_case/x/test_get_shop_info.py
        return ensure_path_sep("/test_case" + os.sep.join(self.spilt_path)) 
    
    @property
    def case_ids(self):
        return [k for k in self.yaml_case_data.keys() if k != "case_common"]
    
    @property
    def get_file_name(self):
        # 这里通过"/" 符号进行分割,提取出来文件名称
        # 判断生成的 testcase 文件名称,需要以test_ 开头
        case_name = self.spilt_path[-1].replace(
            self.spilt_path[-1], "test_" + self.spilt_path[-1]
        )
        return case_name
    
    def mk_dir(self) -> None:
        """ 判断生成自动化代码的文件夹路径是否存在,如果不存在,则自动创建 """
        # _LibDirPath = os.path.split(self.libPagePath(filePath))[0]
        _case_dir_path = os.path.split(self.get_case_path)[0]
        if not os.path.exists(_case_dir_path):
            os.makedirs(_case_dir_path)

    def get_case_automatic(self):
        """自动生成测试用例代码"""
        # 获取配置文件下全部yaml文件
        file_path = get_all_yaml_files(ensure_path_sep("/conf"), yaml_data_switch=True)
        for file in file_path:
            # 判断代理拦截的yaml文件,不生成test_case代码
            if 'proxy_data.yaml' not in file:
                # 获取配置yaml用例数据
                self.yaml_case_data = YamlControl(file).read_yaml_data()
                # yaml文件相对路径
                self.file_path = file
                # 判断用例需要用的文件夹路径是否存在,不存在则创建
                self.mk_dir()
                print(self.gen_file_name, "\n",
                      self.get_test_class_title,"\n",
                      self.get_func_title,"\n",
                      self.get_case_path,"\n",
                      self.case_ids,"\n",
                      self.get_file_name)
                write_testcase_file(allure_epic = self.allure_epic,
                                    allure_feature=self.allure_feature,
                                    allure_story=self.allure_story,
                                    class_title=self.get_test_class_title,
                                    func_title=self.get_func_title,
                                    case_path=self.get_case_path,
                                    case_ids=self.case_ids,
                                    file_name=self.get_file_name)


下一篇介绍用例内容写入/utils/write_testcase_file.py,使用pytest实现自动化


http://www.kler.cn/a/452711.html

相关文章:

  • 群晖Cloud Sync一键同步让数据管理变得简单
  • 医疗平板与普通平板对比:优势尽显
  • PyQt5 学习方法之悟道
  • (六)循环神经网络_基本的RNN
  • git push origin HEAD:refs/for/分支名
  • 极狐GitLab 17.7正式发布,可从 GitLab 丝滑迁移至极狐GitLab【一】
  • Postman最新接口自动化持续集成
  • 虚拟机桥接模式网络连接不上解决方法
  • SQL server学习10-数据库编程(中)
  • 常用的 JVM 调优的参数
  • 【C++多重类循环依赖问题】基于class前向声明与类定义和实现分离的解决方案与分析
  • 解决 Docker 中 DataLoader 多进程错误:共享内存不足
  • ES 集群 A 和 ES 集群 B 数据流通
  • 【数据分析】似然和极大似然估计
  • SQLSERVER、MYSQL LIKE查询特殊字符和转义字符相同与不同
  • 用Python开发高级游戏:实现3D迷宫游戏
  • 【Ubuntu】如何轻松设置80和443端口的防火墙
  • 如何使用Windows快捷键在多显示器间移动窗口
  • Git 代理配置——克隆仓库时遇到 OpenSSL SSL_ERROR_SYSCALL 的解决方案
  • 详解Ollama api (Windows环境)
  • 【QT开发自制小工具】PDF/图片转excel---调用百度OCR API接口
  • 【问题实录】服务器ping不通win11笔记本
  • 【每日学点鸿蒙知识】挖空样式、解密库性能问题、按钮下拉列表弹窗、Scroll组件回调事件问题、判断当前时间之后方法
  • wordpress网站用token登入开发过程
  • Idean 处理一个项目引用另外一个项目jar 但jar版本低的问题
  • 3D几何建模引擎Parasolid功能解析