【Python】将xmind写的测试用例转成禅道可导入的excel格式

xmind转excel的过程

(1)、读取xmind中的内容,使用xmindparser第三方库实现xmind内容的读取
(2)、将内容进行处理后保存至excel中,而本次使用的是pandas库将内容存储到excel中。

脚本中使用到的第三方库

在这里插入图片描述

脚本适用的xmind格式

在这里插入图片描述

读取xmind中的内容

读取xmind中的内容并将内容按行的形式保存至列表中,其中要求xmind中必须要标记优先级,否则将会抛出自定义异常。如下

class ReadXmind:
    def __init__(self) -> None:
        self.__path = None
        self.__title_list = []

    def __read_xmind(self) -> list:
        """读取xmind文件内容

        Returns: 列表

        """
        return xmind_to_dict(self.__path)

    def __get_content(self, topics: list, titles: list) -> None:
        """获取每个分支主题中的标题内容并保存至主主题标题文本列表中

        Args:
            topics: 所有分支主题,格式:list
            titles: 主主题中的标题文本,格式:list

        Returns: None

        """
        for topic in topics:
            tmp_title = copy.deepcopy(titles)  # 将titles列表复制成一个临时变量中
            if "topics" in topic:   # 如果该分支主题存在子分支主题
                tmp_title.append(topic["title"])   # 将该分支主题标题添加至列表临时变量中
                self.__get_content(topic["topics"], tmp_title)  # 回调该函数,获取该分支主题下其他分支主题内容
            else:  # 如果该分支主题不存在子分支主题
                tmp_title.append(topic["title"])  # 将该分支主题标题添加至列表临时变量中
                if "makers" in topic:   # 该分支主题存在标记
                    # 过滤出优先级标记 , 并取出优先级的值
                    priority = ''.join(list(filter(lambda x: 'priority' in x, topic["makers"])))[-1]
                    tmp_title.append({'priority': priority})  # 将优先级以字典的形式添加至列表临时变量中
                else:
                    raise MarkerError(f"<{tmp_title[0]}>-<{tmp_title[1]}>-<{tmp_title[2]}>-<{tmp_title[3]}>中未标记优先级")
                self.__title_list.append(tmp_title)

    def content(self, x_path: str) -> list:
        """获取xmind文件中每个主题的标题内容

        Args:
            x_path: xmind文件路径及文件名称

        Returns: 标题内容列表

        """
        self.__path = x_path
        topics = self.__read_xmind()
        for topic in topics:
            if "topics" not in topic['topic']:
                raise TopicError(f"<{topic['topic']['title']}>主题无分支主题")
            self.__get_content(topic['topic']['topics'], [topic['topic']['title']])
        return self.__title_list

    def get_title_list(self):
        """获取标题列表数据

        Returns: 标题列表
        """
        return self.__title_list
处理读取的xmind数据

因xmind中的内容只有topic和title 信息,在转换的刚才中无法知晓哪个节点属于哪块内容,故在提取数据时采用的是人为标记节点标题的方式。

def data_process(data_list) -> list:
    """
    数据处理
    Args:
        data_list: 待处理的数据列表

    Returns: 处理完成的数据列表

    """
    result = []
    for index, data in enumerate(data_list):
        priority = data[-1]['priority']  # 优先级
        applicable_stage = '系统测试阶段\n冒烟测试阶段' if priority == '1' else '系统测试阶段'   # 测试阶段
        pre_condition_index = element_index(data, ('前置条件', '预置条件', '前提条件'))   # 前置条件所在的位置
        title_index = element_index(data, ('业务', '功能', '其他'))   # 确定标题所在的位置

        # 判断是否存在标题,并对标题标识的文本加上【】符号
        if title_index != -1:
            data[title_index] = f'【{data[title_index]}】' if all(a not in data[title_index] for a in ['【', '】']) \
                else data[title_index]
        else:
            raise TextNotExistError(f"<{data[0]}> 中 业务/功能/其他 文本在内容中不存在")

        # 判断是否存在前置条件(前置条件需要写在标题和步骤之间)
        if pre_condition_index != -1:
            # 将('前置条件'\'预置条件')文本所在位置~步骤之间的主题值置为前置条件
            pre_condition = re.sub('(前置条件|预置条件|前提条件)(:|:)', '', ''.join(data[pre_condition_index: -3]))
            # 将('业务'\'功能'\'其他')文本所在位置~前置条件所在位置之间的主题值置为标题
            case_title = ''.join(data[title_index: pre_condition_index])
        else:
            pre_condition = ''
            case_title = ''.join(data[title_index: -3])  # 将('业务'\'功能'\'其他')文本所在位置~步骤之间的主题值置为标题

        case_module = '/'.join(data[: title_index])  # 所属模块(将主主题到标题所有在位置的主题合并为所属模块)
        case_step = data[-3]   # 步骤
        case_expect = data[-2]  # 预期
        result.append([case_module, case_title, pre_condition, case_step, case_expect, '', priority, '功能测试',
                       applicable_stage])

    return result


def element_index(data: list, search_key: tuple):
    """ 查找关键字在列表中的位置,多个关键字时前一个关键字匹配成功后,就返回下标

    Args:
        data: 待查询的列表数据
        search_key: 需要搜索的关键字

    Returns: 返回关键字在列表中的位置
    """

    filter_value = list(filter(lambda d: any(a in d[1] for a in search_key), enumerate(data)))
    return -1 if len(filter_value) == 0 else filter_value[0][0]
将处理后的列表数据保存至excel

使用pandas 库将列表数据插入并保存到excel中;这需要数据处理结果中返回的是一个二维列表,且列表中每行需要有9列。

def to_excel(excel_name, data_list, sheet='sheet1'):
    """ 将列表数据保存至excel文档中

    Args:
        excel_name: excel文件的名称(包含路径;如果不包含路径则默认保存至当前项目路径是在文件夹)
        data_list: 待保存至excel中的数据列表
        sheet: 指定保存的sheet名称,默认名称为 sheet1

    Returns: None
    """
    # 设置excel表格中的列名
    columns = ["所属模块", "用例标题", "前置条件", "步骤", "预期", "关键词", "优先级", "用例类型", "适用阶段"]
    df = pd.DataFrame([], columns=columns, index=[])

    for index, value in enumerate(data_process(data_list)):
        df.loc[index] = value

    # 保存excel 文档
    df.to_excel(excel_name, sheet, index=False)

脚本中使用到的自定义异常

class BasicValueError(ValueError):
    pass


class MarkerError(BasicValueError):
    pass


class TopicError(BasicValueError):
    pass


class TextNotExistError(BasicValueError):
    pass
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值