测试框架开发(2) 之测试结果的树形映射

import time
from enum import Enum


# 工具函数
def getlocaltime():
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))

def _get_intent(self,indent):
    return "+" * ( indent *2  )

def _get_dot_line(self,line,line_max):
    if len(line)>(line_max):
        return line
    else:
        return "-"*(line_max - len(line))

# 定义节点类型
class NodeType(Enum):
    Step = 1
    Case = 2
    TestList = 4
    Other = 256


# 节点状态
class StepResult(Enum):
     INFO =1
     PASS =2
     FAIL = 4
     EXCEPTION = 8
     WARNING = 16
     ERROR = 32


# 实现测试节点类
class ResultNode:
    def __init__(self,header,
                 status=None ,
                 msg = "",
                 parent = None ,
                 node_type = NodeType.Other):
        self.status = StepResult.INFO if status is None else status
        self.header = header
        self.msg = msg
        self.children =list()
        self.parent = parent
        self.type = node_type
        self.timestamp = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))


    def add_child(self,header,
                  status=None ,
                  msg = "",
                  parent = None ,
                  node_type = NodeType.Other):

        """添加新的子节点,并返回该节点"""
        new_node = ResultNode(header,
                              msg = msg,
                              parent = self,
                              node_type = node_type) # 实例化一个节点对象
        # 节点类型过滤,类型只能为step
        if self.type in[NodeType.Step,NodeType.Case]:
            new_node.type = NodeType.Step
        self.children.append(new_node)
        # for i in self.children:
        #     print("testlog-",i.msg)
        new_node.set_status(status)
        return new_node


    def set_status(self,status):
        """设置当前节点的状态,同时更新父节点的状态"""
        # 【设计逻辑】
        # 对于以下节点不做父节点进一步设置:
        # ---1、非case节点
        # ---2、step节点
        if self.type  == NodeType.Other or status  == StepResult.INFO:
            return

        # 只有以下节点更新当前状态
        # ---状态为PASS
        if self.status == StepResult.PASS:
            self.status = status

        # self.parent.set_status(status)



    def is_leaf(self):
        return any(self.children)


    def to_dict(self):
        """将当前节点实例结果生成字典类型的结构"""
        rv = dict()
        rv["header"] = self.header
        rv["status"] = self.status.value
        rv["msg"] = self.msg
        rv["type"] = self.type #?
        rv["timstamp"] = self.timestamp
        rv["children"] = list()
        # 遍历当前节点实例,将当前节点的子节点信息值存入字典的children键中
        for child in self.children:
            # print("result",child.to_dict())
            rv["children"].append(child.to_dict())
        return rv

    def to_excel(self):
        """将结果生成excel类型的结构"""
        pass


    def to_text(self,indent = 0):
        """将结果生成文本类型的的结构"""
        pass

    def get_test_case_stats(self):
        stats_pass = 0
        stats_fail = 0
        stats_error = 0
        stats_exception = 0
        if self.type == NodeType.Case:
            if self.status == StepResult.PASS:
                stats_pass = 1
            elif self.status == StepResult.FAIL:
                stats_fail = 1
            elif self.status == StepResult.EXCEPTION:
                stats_exception =1
            elif self.status == StepResult.WARNING:
                stats_

class ResultReporter:
    def __init__(self):
        """
        【root】 :根节点
        【recent_node】 :保存当前操作的节点,在ResultReporter类初始化的过程中,【recent_node】被赋值为【root】
        """
        self.root = ResultNode("Root")
        self.recent_node = self.root    # recent_node:保存当前操作的节点,每次执行完函数add_node()后,将新的节点赋给recent_node
        self.recent_case = None         # recent_test:用来存放测试用例
        self.recent_list = None         # recent_list:用来存放测试列表



# ------------------------------------------------------------------------------------------
    # node节点管理
    def add_node(self,header,msg="", status=StepResult.INFO, node_type=NodeType.Other):
        """
        【add_node()】 :通过调用当前节点的add_child方法来添加新的节点,并且将新建的节点赋值给recent_node
        【pop()】
        """
        self.recent_node = self.recent_node.add_child(header = header,
                                                      status = status,
                                                      msg = msg,
                                                      node_type = node_type)

    def end_node(self):
        # 如果存在父节点:那么当前节点recent_node的值 ==>退回设置至当前节点的父节点
        if self.recent_node.parent:
            self.recent_node = self.recent_node.parent

# ------------------------------------------------------------------------------------------
    #测试列表层(TestList)
    def add_list(self,list_name):
        """添加测试列表"""
        self.recent_node.add_child(msg = "新增测试列表",header=list_name, node_type=NodeType.TestList)
        self.recent_list = self.recent_node


    def end_list(self):
        """退出当前测试列表,end_list()用于保证当前操作节点能最终回到正确的位置"""
        if self.recent_list is None:
            return
        self.recent_node = self.recent_list.parent # 测试列表发生异常,更新当前操作节点到父节点
        self.recent_list = None



# ------------------------------------------------------------------------------------------
    # 测试用例层(Case)
    def add_test(self,case_name):
        """添加测试用例"""
        self.recent_node.add_child(msg = "新增测试用例",header = case_name ,node_type=NodeType.Case)
        self.recent_case =self.recent_node

    def end_test(self):
        """测试步骤发生异常时使用,end_ test()用于保证当前操作节点能最终回到正确的位置"""
        if self.recent_case is None:
            return
        self.recent_node = self.recent_case.parent  # 测试用例发生异常,更新当前操作节点到父节点
        self.recent_case = None

# ------------------------------------------------------------------------------------------
    # 测试步骤组层(step)
    def add_step_group(self,group_name):
        """添加测试步骤组"""
        self.recent_node = self.recent_node.add_child(msg = "新增测试步骤组",header = group_name ,node_type=NodeType.Step)
        self.recent_step_group = self.recent_node

    def end_step_group(self):
        self.end_node()

    def add(self,status:StepResult,headline,msg =""):
        """用来添加新的叶节点"""
        self.recent_node.add_child(header=headline,
                                   msg = msg,
                                   node_type=NodeType.Step,
                                   status=status)


# RN = ResultNode(1,None ,msg="测试顶层节点NODE1",parent = None ,node_type=1)
# RN.add_child(2,status=2 ,msg="测试N+1层节点1" ,parent="NODE1" ,node_type=2)
# RN.add_child(3,status=2 ,msg="测试N+1层节点2" ,parent="NODE1" ,node_type=2)
# RN.set_status(StepResult.PASS)
# print("Rn节点的所有节点信息(顶层节点和子节点):")
# print(RN.to_dict())

OBJ = ResultReporter()
OBJ.add_list("测试列表1")
OBJ.add_test("测试用例1:登录软件")

OBJ.add_step_group("启动")
OBJ.add(StepResult.PASS,"点击电源键","已完成")
OBJ.end_step_group()

OBJ.add_step_group("登录账户")
OBJ.add(StepResult.PASS,"输入用户usr111","已完成")
OBJ.end_step_group()

OBJ.add_step_group("输入密码")
OBJ.add(StepResult.PASS,"输入密码123","已完成")
OBJ.end_step_group()

# OBJ.end_test()


OBJ.add_test("测试用例2:退出软件")

OBJ.add_step_group("点击退出")
OBJ.add(StepResult.PASS,"点击退出按键","已完成")
OBJ.end_step_group()

OBJ.add_step_group("确认退出")
OBJ.add(StepResult.PASS,"点击是","已完成")
OBJ.end_step_group()
OBJ.end_test()

print(OBJ.root.to_dict())

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值