接口自动化,excel用例转yaml用例

news/2024/7/21 4:18:45 标签: 自动化, excel, python, pytest
python">import json
import re
import xlrd as xr
import yaml  # pip install ruamel.yaml
import os
from ruamel import yaml
from collections import OrderedDict

from ruamel.yaml.compat import ordereddict
import ruamel.yaml.comments


class Excel2Yapi:
    # 获取excel内容并转为json,再换成yaml
    def excel2yapi(self, file):
        wb = xr.open_workbook(file)
        sheetList = wb.sheet_names()
        sh = wb.sheet_by_name(sheetList[0])
        for sheet_name in sheetList:
            # 初始化一个yaml
            file = sheet_name+'.yaml'
            self.initYaml(file, title=sheet_name)
            sh = wb.sheet_by_name(sheet_name)
            # 遍历excel,让每一行数据写入到yaml的test_step
            if sh.nrows < 2:
                continue
            else:
                for row in range(1, sh.nrows):
                    # 首行列名与某一行的值映射成字典
                    row_value = dict(zip(sh.row_values(0), sh.row_values(row)))
                    js = {}
                    js['api_service'] = row_value['application']
                    rootdir = 'D:\\02-软件\\pythonProject\\w_Test\\Yaml'
                    self._mapApiName(rootdir, row_value, js)
                    # 需要加个匹配api_name的方法,通过url去匹配
                    for key in row_value.keys():
                        self._mapping(key, row_value, js)
                    self.addServiceStep(file, js)
                    print(row_value)

    # 通过url匹配接口模板
    def _mapApiName(self,rootdir, row_values, js):
        file_list = self.get_allFile(rootdir)
        for file in file_list:
            with open(file, 'r', encoding='utf-8') as f:
                doc = yaml.round_trip_load(f)
                if ('api_info' in doc.keys()) and ('address' in doc['api_info'].keys()):
                    if self.replaceVar(doc['api_info']['address']) == self.replaceVar(row_values['url']):
                        names = file.split('\\')
                        js['api_name'] = names[-1].split('.')[0]
                        break

    def replaceVar(self, s):
        rule = "\$\{.*?\}"  # 变量匹配规则,目前为${xxxxx}
        rule2 = "\{.*?\}"   # 变量匹配规则,目前为{xxxxx}
        rule3 = '/'         # 变量匹配规则,目前为/
        s = re.sub(rule, '', s)
        s = re.sub(rule2, '', s)
        s = re.sub(rule3, '', s)
        return s

    # 映射excel的每个单元格到yaml的字段
    def _mapping(self, key, row_value, js):
        if row_value[key] == '':
            return
        elif key =='application' or key == 'url' or key == 'method' or key == 'priority' or key == 'scenario' or key == 'auth':
            return
        elif key == 'set_up':
            self._toTestCase(row_value, js, key, key)
            self._toTestCase(row_value, js, key, 'tear_down')
        elif key == 'filename':
            self._toTestCase(row_value, js, key, 'file')
        elif key == 'expectedRes':
            #s = json.loads(row_value['expectedRes'].replace('\n', ''))
            self._toCheck(row_value, js)
        elif key == 'var_from_body':
            self._toRelevance(row_value, js, key, 'body.')
        elif key == 'var_from_db':
            self._toRelevance(row_value, js, key, 'db.')
        elif key == 'var_from_res':
            self._toRelevance(row_value, js, key, 'res.')
        else:
            self._toTestCase(row_value, js, key, key)

    # excel用例各参数写入yaml的check
    def _toCheck(self, row_value, js):
        s = json.loads(row_value['expectedRes'])
        for s_key in s.keys():
            if 'check' in js['test_case']:
                if s_key == "code" or s_key == "status":
                    js['test_case']['check']['status'] = s[s_key]
                if s_key == "sql":
                    js['test_case']['check']['db'] = s[s_key]
                else:
                    js['test_case']['check'][s_key] = str(s[s_key])
            else:
                js['test_case']['check'] = {}
                if s_key == "code" or s_key == "status":
                    js['test_case']['check']['status'] = s[s_key]
                if s_key == "sql":
                    js['test_case']['check']['db'] = s[s_key]
                else:
                    js['test_case']['check'][s_key] = str(s[s_key])

    # excel用例各参数写入yaml的Relevance
    def _toRelevance(self, row_value, js, old_key, prefix):
        s = json.loads(row_value[old_key])
        if 'relevance' in js['test_case']:
            for s_key in s.keys():
                js['test_case']['relevance'][s_key] = prefix + row_value[old_key]
        else:
            js['test_case']['relevance'] = {}
            for s_key in s.keys():
                js['test_case']['relevance'][s_key] = prefix + row_value[old_key]

    # excel用例各参数写入yaml的test_case
    def _toTestCase(self, row_value, js, old_key, new_key):
        if 'test_case' in js:
            #row_value[old_key] = json.loads(row_value[old_key].replace('\n', ''))
            if old_key == 'header' or old_key == 'body':
                row_value[old_key] = re.sub(r'\[', '\"[', row_value[old_key])
                row_value[old_key] = re.sub(r'\]', ']\"', row_value[old_key])
                row_value[old_key] = json.loads(row_value[old_key])
                row_value[old_key] = str(row_value[old_key])
                row_value[old_key] = re.sub(r'\'\[', '[', row_value[old_key])
                row_value[old_key] = re.sub(r']\'', ']', row_value[old_key])
            js['test_case'][new_key] = row_value[old_key]
        else:
            js['test_case'] = {}
            js['test_case'][new_key] = row_value[old_key]

    # 生成yaml文件,暂无引用
    @staticmethod
    def writeYaml(file, data):
        # 数据写入到yaml文件中,使用dump函数,将python数据转换为yaml数据,并保存在文件中
        with open(file, 'w', encoding='utf-8') as f:
            yaml.round_trip_dump(data, f, default_flow_style=False, allow_unicode=True)

    # 获取excel表格对应列,暂无引用
    @staticmethod
    def getColumn():
        column = {"yes or no": 0, "ID": 1, "name": 2, "priority": 3, "application": 4, "url": 5, "method": 6,
                  "set_up": 7, "header": 8, "params": 9, "body": 10, "filename": 11, "expectedRes": 12,
                  "var_from_body": 13, "var_from_db": 14, "var_from_res": 15, "wait_untile": 16, "scenario": 17,
                  "auth": 18}
        return column

    def getDictValue(self, dic, c):
        pass

    # 更新yaml字段内容,file文件,keyPath文件中需要修改的参数(用.隔开),value新的值,可能不适用于列表,暂无引用
    def updateYaml(self, file, keyPath, value):
        with open(file, 'r', encoding='utf-8') as f:
            current_yaml = yaml.round_trip_load(f)
            print(current_yaml)
            keys = keyPath.split('.')
            keys_num = len(keys)
            if keys_num == 1:
                current_yaml[keys[0]] = value
            elif keys_num == 2:
                current_yaml[keys[0]][keys[1]] = value
            elif keys_num == 3:
                current_yaml[keys[0]][keys[1]][keys[2]] = value
            elif keys_num == 4:
                current_yaml[keys[0]][keys[1]][keys[2]][keys[3]] = value
            else:
                print('字典路径超出范围,不与修改')
        if current_yaml:
            with open(file, 'w', encoding='utf-8') as f_new:
                yaml.round_trip_dump(current_yaml, f_new, default_flow_style=False)

    # file需要使用固定的模板,
    def addServiceStep(self, file, data):
        with open(file, 'r', encoding='utf-8') as f:
            doc = yaml.round_trip_load(f)
            # 传入的data如下,是一个step
            # data = {'api_service': 'dome3', 'api_name': 'demo_api10(download)','test_case': {'check': {}, 'relevance': {}}}
            doc['test_step'].append(data)
            if doc['test_step'][0] is None:
                del doc['test_step'][0]
        with open(file, 'w', encoding='utf-8') as f:
            yaml.round_trip_dump(doc, f, default_flow_style=False)

    # 初始化一个yaml模板,用于后续写入用例
    def initYaml(self, file, testcase_id=None, title=None, priority=1, version=None):
        data = {'testcase_id': testcase_id, 'title': title, 'priority': priority, 'version': version, 'test_step': [None]}
        with open(file, 'w', encoding='utf-8') as f:
            yaml.round_trip_dump(data, f, default_flow_style=False)

    def get_allFile(self, rootdir):
        file_list = []
        for root, dirs, files in os.walk(rootdir):
            for file in files:  # 遍历目录里的所有文件
                print(os.path.join(root, file), " --- file")
                file_list.append(os.path.join(root, file))
        return file_list



if __name__ == "__main__":
    file = 'E:\\API_test\\openAPITest\\QA\\QA\\szapitest\\Graphx\\testdata\\release-test\\TC000001-后台中心-租户用户角色操作校验.xlsx'
    ey = Excel2Yapi()
    ey.excel2yapi(file)
    path = 'E:\\API_test\\openAPITest\\QA\\QA\\szapitest\\Graphx\\testdata'
    print(ey.get_allFile(path))

# ey.updateYaml('demo_api1.yaml', 'testcase.test.abc', 'yes')
# ey.addYaml('demo_test.yaml')


# doc = {'testcase_id': None, 'title': None, 'priority': None, 'version': None, 'test_step': [None]}
# with open('demo_test.yaml', 'w', encoding='utf-8') as f:
#     yaml.round_trip_dump(doc, f, default_flow_style=False)
# with open('demo_test.yaml', 'r', encoding='utf-8') as f:
#     doc = yaml.round_trip_load(f)
#     print(doc)
#     dic = {'api_service': 'dome3', 'api_name': 'demo_api10(download)', 'test_case': {'check': {}, 'relevance': {}}}
#     doc['test_step'].append(dic)
#     if doc['test_step'][0] == None:
#         del doc['test_step'][0]
# with open('demo_test.yaml', 'w', encoding='utf-8') as f:
#     yaml.round_trip_dump(doc, f, default_flow_style=False)


http://www.niftyadmin.cn/n/410668.html

相关文章

【已解决】qt4安装包下载含下载链接(完全版)

总所周知&#xff0c;c qt4.8是一个稳定版本&#xff0c;而qt4.8去网上找的我好辛苦&#xff0c;而且官网时而挂机一样&#xff0c;网站崩溃一样&#xff0c;即使找到了&#xff0c;它们也会让你下载qt4.8版本&#xff0c;而那些&#xff0c;比如这里就会显得手足无措。 问题…

钉钉去除默认的导航栏

在App.vue中import * as dd from dingtalk-jsapi;onLaunch() {dd.biz.navigation.hideBar({hidden: true, // true&#xff1a;隐藏&#xff0c;false&#xff1a;显示onSuccess: function(result) {console.log(result, result)},onFail: function(err) {console.log(err, err…

人工智能-实验四

第四次实验 一.实验目的 ​ 了解深度学习的基本原理。能够使用深度学习开源工具。学习使用深度学习算法求解实际问题。 二.实验原理 1.深度学习概述 ​ 深度学习源于人工神经网络&#xff0c;本质是构建多层隐藏层的人工神经网络&#xff0c;通过卷积&#xff0c;池化&…

【SQL Server】数据库开发指南(九)详细讲解 MS-SQL 触发器的的创建、修改、应用与适用场景

本系列博文还在更新中&#xff0c;收录在专栏&#xff1a;#MS-SQL Server 专栏中。 本系列文章列表如下&#xff1a; 【SQL Server】 Linux 运维下对 SQL Server 进行安装、升级、回滚、卸载操作 【SQL Server】数据库开发指南&#xff08;一&#xff09;数据库设计的核心概念…

xxl-job Study Notes

文章目录 1 xxl-job 快速入门1.1 xxl-job是什么1.2 为什么需要xxl-job1.2.1 定时任务1.2.2 分布式任务调度1.2.3 分布式任务调度特点 1.3 xxl-job简介1.4 部署安装——基于docker1.5 xxl-job表介绍1.5 编写任务代码1.5.1 xxl-job配置1.5.2 任务代码1.5.3 分布式任务测试1.5.3.1…

S32DS的安装教程参考

进入恩智浦官网 点击右上角注册登陆进行注册账号->注册成功后登录成功显示为"我的恩智浦" 1.我使用的是 S32 DS for Power Architecture v2.1 当然可以根据自己需求下载相应软件版本 2.点击搜索框,输入S32ds,回车enter 3.找到相应信息&#xff0c;点击蓝字(有…

nodejs+vue+elementui校园车辆校车管理系统

开发语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 本界面为学生用车信息的添加界面 本界面是校园车辆的使用记录信息&#xff0c;包括校车的编号&#xff0c;校车的名称&#xff0…

Springmvc面试题(基础篇)

目录 一、概述 1、springmvc有什么用&#xff1f; 2、springmvc的执行流程&#xff1f; 二、注解 3、说一说常用的springmvc注解 4、刚才你提到了RequestMapping&#xff0c;它具体是做什么的&#xff1f;怎么用呢&#xff1f; 5、你知道Restful风格吗&#xff1f; 6、…