xmind用例数据上传至禅道

news2024/7/4 4:30:32

 xmind格式参考,只需要在一级子主题填写对应用例模块ID,其余格式随意即可生成用例并直接上传到禅道:

 代码里需填写禅道对应登录账号及用例所属产品

import requests
import json
import re
import hashlib
import pprint
import threading
from xmindparser import xmind_to_dict


def get_sub_topic(topic_data_list, k=0, row=None, result=None):
    '''遍历出所有数据'''
    if row is None:
        row = {}
    if result is None:
        result = []
    for topic_data in topic_data_list:
        # 获取下一行时,清除上一行针对当前索引后面的数据
        k_list = []
        for j in row:
            k_list.append(j)
        for j in k_list:
            if j > k:
                row.pop(j)
        # 赋值当前索引 标题
        row[k] = topic_data['title']
        if 'topics' in topic_data:
            get_sub_topic(topic_data['topics'], k=k + 1, row=row, result=result)
        else:
            result.append(row.copy())
    return result


def get_xmind_data(xmind_file_path):
    data = xmind_to_dict(xmind_file_path)
    topics = data[0]['topic']['topics']
    result = get_sub_topic(topics)
    return result


def get_max_length(data):
    length = 0
    for l in data:
        length = len(l) if len(l) > length else length
    return length


def get_length_first_name(length, data):
    for l in data:
        if length == len(l):
            if length > 4:
                return l[-4], length - 4
            else:
                return l[1], 1


def get_case(title, data: list, index):
    row = []
    tag = -1
    for i, l in enumerate(data):
        if len(l) > index and l[index] == title:
            if tag == -1 or i == tag + 1:
                row.append(l)
                tag = i
    for r in row:
        data.remove(r)
    return row


def case_to_params(row: list, index: int):
    case = {}
    module: str = row[0][0]
    module_id = re.search('#\d+', module)
    if module_id is None:
        return
    module_id = module_id.group()
    row[0][0] = module.replace(f'({module_id})', '').replace(f'({module_id})', '')
    case['module'] = module_id[1:]
    case['title'] = '-'.join(row[0][:index + 1])
    row = [r[index + 1:] for r in row]
    three = []
    group = {}
    for r in row:
        if len(r) == 3:
            three.append(r[0]) if r[0] not in three else ''
    for t in three:
        group[t] = []
        for r in row:
            if r[0] == t:
                group[t].append(r[1:])

    num = 1
    oo = []
    for o in row:
        if len(o)==0:
            continue
        if o[0] in three and o[0] not in oo:
            case[f'steps[{num}]'] = o[0]
            case[f'stepType[{num}]'] = 'group'
            j = 1
            pp = []
            for rr in group[o[0]]:
                num_key = f'{num}.{j}'
                if len(rr) == 1:
                    case[f'steps[{num_key}]'] = rr[0]
                    case[f'stepType[{num_key}]'] = 'item'
                    case[f'expects[{num_key}]'] = ''
                    j += 1
                elif len(rr) == 2:
                    if rr[0] not in pp:
                        case[f'steps[{num_key}]'] = rr[0]
                        case[f'stepType[{num_key}]'] = 'item'
                        case[f'expects[{num_key}]'] = rr[1]
                        j += 1
                        pp.append(rr[0])
                    else:
                        num_key = f'{num}.{j - 1}'
                        case[f'expects[{num_key}]'] += f'\n{rr[1]}'
            oo.append(o[0])
            num += 1
        elif o[0] in three:
            continue
        elif len(o) == 1:
            case[f'steps[{num}]'] = o[0]
            case[f'stepType[{num}]'] = 'item'
            case[f'expects[{num}]'] = ''
            num += 1
        elif len(o) == 2:
            if o[0] not in oo:
                case[f'steps[{num}]'] = o[0]
                case[f'stepType[{num}]'] = 'step'
                case[f'expects[{num}]'] = o[1]
                num += 1
                oo.append(o[0])
            else:
                case[f'expects[{num - 1}]'] += f'\n{o[1]}'
    return case


host = 'https://rhjs.techgp.cn/'


def md5update(args):
    input_name = hashlib.md5()
    input_name.update(args.encode("utf-8"))
    return input_name.hexdigest()


class CaseUpload:

    @staticmethod
    def __get_session():
        url = '{}/api-getsessionid.json'.format(host, )
        rj = requests.get(url)
        data = rj.json()['data']
        if isinstance(data, str):
            data = json.loads(data)
        return data['sessionID']

    def login(self, username, password):
        sid = self.__get_session()
        url = '{}/user-login.json?account={}&password={}&zentaosid={}'.format(host, username, password, sid)
        rj = requests.get(url)
        res = rj.json()
        if res['status'] == 'success':
            return {
                'sid': sid,
                'username': username,
                'password': md5update(password),
                'nickname': res['user']['realname'],
                'email': res['user']['email']
            }
        return False

    def create_case(self, sid, product, payload):
        module = payload['module']
        form = {'product': str(product), 'type': 'feature', 'stage[]': '',
                'story': '0', 'color': '', 'pri': '3', 'precondition': '',
                'keywords': '', 'status': 'wait', 'labels[]': '', 'files[]': ''}
        url = f'{host}/zentao/testcase-create-{product}-0-{module}.json?zentaosid={sid}'
        form.update(payload)
        files = []
        response = requests.request("POST", url, data=form, files=files)
        print('response create', response.text)


def main(xmind_file_path, product: str, account: dict, ):
    '''
    :param xmind_file_path:
    :param account: {'username':'xx.li','password':'123456'}
    :return:
    '''
    data = get_xmind_data(xmind_file_path)
    data = [[i for i in l.values()] for l in data]
    case_list = []
    while data:
        max_length = get_max_length(data)
        title, index = get_length_first_name(max_length, data)
        row = get_case(title, data, index)
        # print('row::',row)
        case = case_to_params(row, index)
        case_list.append(case)
    pprint.pprint(case_list)
    print(len(case_list))
    case_upload=CaseUpload()
    sid = case_upload.login(**account)['sid']
    tlist=[]
    for _case in case_list:
        t=threading.Thread(target=case_upload.create_case,args=(sid,product,_case))
        # case_upload.create_case(sid,product,_case)
        tlist.append(t)
        t.start()
    for t in tlist:
        t.join()


if __name__ == '__main__':
    main('/Users/xx/Desktop/cases/大数据/数字化v1.1.1.xmind', '248',
         {
             'username': 'xx',
             'password': 'xx'
         })

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/866614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

并发——Atomic 原子类总结

文章目录 1 Atomic 原子类介绍2 基本类型原子类2.1 基本类型原子类介绍2.2 AtomicInteger 常见方法使用2.3 基本数据类型原子类的优势2.4 AtomicInteger 线程安全原理简单分析 3 数组类型原子类3.1 数组类型原子类介绍3.2 AtomicIntegerArray 常见方法使用 4 引用类型原子类4.1…

段页式储存结构

题目:假设段页式储存结构系统中的地址结构如下图所示 从图中可知段号22-31占了10位,页号12-21占了10位,页内地址0-11占了12位 段: 最多有2^101024个段 页:每段最大允许2^101024个页 页的大小: 2^124x2^1…

【C++精华铺】6.C++类和对象(下)类与对象的知识补充及编译器优化

目录 1. 再谈构造 1.1 成员变量的初始化(初始化列表) 1.2 初始化列表的行为 1.3 explicit关键字 2. 类中的static成员 2.1 静态成员变量 2.2 静态成员函数 3. 友元 3.1 友元函数 3.1 友元类 4. 内部类 5. 匿名对象 6. 对象拷贝时候的编译器优化…

Linux网络编程 socket编程篇(一) socket编程基础

目录 一、预备知识 1.IP地址 2.端口号 3.网络通信 4.TCP协议简介 5.UDP协议简介 6.网络字节序 二、socket 1.什么是socket(套接字)? 2.为什么要有套接字? 3.套接字的主要类型 拓】网络套接字 三、socket API 1.socket API是什么? 2.为什么…

Qt通过QSS设置QPushButton的样式

同时设置QPushButton的文字样式和图标的方法 为了美化界面,有时候需要修改QPushButton的样式,让一个QPushButton上面既要显示图标,又要显示文字内容 起初我的做法是重写QPushButton,这样做可以实现,但是有几个问题 实现…

【数学建模】逻辑回归算法(Logistic Resgression)

逻辑回归算法 简介逻辑回归与条件概率绘制sigmoid函数 简介 逻辑回归算法是一种简单但功能强大的二元线性分类算法。需要注意的是,尽管"逻辑回归"名字带有“回归”二字,但逻辑回归是一个分类算法,而不是回归算法。 我认为&#xff…

通达OA SQL注入漏洞【CVE-2023-4165】

通达OA SQL注入漏洞【CVE-2023-4165】 一、产品简介二、漏洞概述三、影响范围四、复现环境POC小龙POC检测工具: 五、修复建议 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损…

PHP最简单自定义自己的框架实现像TP链式sql语句(六)

1、实现效果,链式sql语句封装 order、where、group、limit等封装 2、数据表构造函数入参,ModelBase.php public $table NULL; public function __construct($table){$this->table$table;if(!$this->table){die("no table" );}$this-&…

C语言----输入scanf和输出printf详解

C语言编程中,输入输出是基本操作,printf和scanf并不是C语言中的唯一的输入输出选择,对于输入有scanf()、getchar()、getche()、getch()、gets();对于输出有printf()、puts()、putchar(),他们各有自己的使用场景&#x…

C语言案例 阶乘求和-12

题目:求1 2!3! … 20!的和。 程序分析 阶乘相关原理:一个正整数的阶乘是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!,任何大于1的自然数n阶乘表示方法:…

StarRocks入门部署

目录 一、StarRocks整体介绍 1.1、系统架构图: 1.2、FE相关 1.3、BE相关 1.4、数据管理特性 二、简单部署 2.1、部署前准备 2.2、手动部署 2.2.1、部署Leader FE节点 2.2.2、部署BE节点 2.2.3、关联FE、BE,搭建StarRocks集群 2.2.4、给root设…

【深度学习】日常笔记16

可以将pd.DataFrame数据结构理解为类似于Excel中的表格。pd.DataFrame是pandas库提供的一个二维数据结构,用于存储和操作具有行和列的数据。它类似于Excel中的工作表,其中每一列可以是不同的数据类型(例如整数、浮点数、字符串等)…

接口防护电路

一、接口电路是电路中与用户或者外界媒介进行交互的部分,是内部核心敏感电路和外部设备进行信息交互的桥梁。接口电路一般分为输入接口电路和输出接口电路两种。接口电路的防护设计就是为了隔离外部危险的信号,防止外部干扰信息进入系统内部核心敏感电路…

Linux系统USB转串口芯片 GPIO使用教程

一、简介 WCH的多款USB转单路/多路异步串口芯片,除串口接口以外,还提供独立的GPIO接口,各GPIO引脚支持独立的输出输入,GPIO功能的使用需要与计算机端厂商驱动程序和应用软件配合使用。各芯片的默认GPIO引脚状态有所区别&#xff…

Redis——常见数据结构与单线程模型

Redis中的数据结构 Redis中所有的数据都是基于key,value实现的,这里的数据结构指的是value有不同的类型。 当前版本Redis支持10种数据类型,下面介绍常用的五种数据类型 底层编码 Redis在实现上述数据结构时,会在源码有特定的…

RCNA——单臂路由

一,实验背景 之前的VLAN实现的很多都是相同部门互相访问,不同部门无法访问。不过这次整来了一个路由器,领导说大部分的部门虽说有保密信息需要互相隔离,但是这些部门和其它部门也应该互相连通以方便工作交流。因此要配置新的环境&…

2023-08-11 LeetCode每日一题(矩阵对角线元素的和)

2023-08-11每日一题 一、题目编号 1572. 矩阵对角线元素的和二、题目链接 点击跳转到题目位置 三、题目描述 给你一个正方形矩阵 mat,请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 示例 1&#xff1…

linux安装ftp

一、安装 参考博客 https://blog.csdn.net/dafeigecsdn/article/details/126518069 rpm -qa |grep vsftpd # 查看是否安装ftp yum -y install vsftpd # 安装vsftpuseradd -d /home/lanren312 lanren312 # 指定在/home目录下创建用户 passwd lanren312 # 给用户设置密码 # 输…

2022年03月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536 输入 只有一行,一个双精度浮点数。 输出 一行,保留8位小数的浮点数。 样例输…

【Unity每日一记】让一个物体按余弦曲线移动—(三角函数的简单运用)

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:uni…