调整AbstractDispatcher及其子类实例字段的定义并增加字段注释

This commit is contained in:
azhengzz 2021-03-10 17:11:22 +08:00
parent 09a2ae725e
commit 9873a775b5
7 changed files with 156 additions and 53 deletions

View File

@ -21,11 +21,24 @@ class DebugCaseDispatcher(AbstractCaseDispatcher):
:type dispatcher: Dispatcher
"""
super().__init__(case=case, dispatcher_type=dispatcher_type, logger=logger, dispatcher=dispatcher)
# 请求对象
self.request_ = None
self.postprocessor_failure = ''
self.postprocessor_failure_message = ''
# 后处理脚本断言结果
self.postprocessor_failure = None
# 后处理脚本错误信息
self.postprocessor_failure_message = None
# 组件期望断言结果
self.expectations_result = False
# debug请求字段
self.project_variable = None
self.expectation_logic = None
self.postprocessor_script = None
self.expectations = None
def set_up(self):
super().set_up()
# 预处理脚本执行

View File

@ -25,12 +25,36 @@ class HTTPCaseDispatcher(AbstractCaseDispatcher):
:type dispatcher: Dispatcher
"""
super().__init__(case=case, dispatcher_type=dispatcher_type, logger=logger, dispatcher=dispatcher)
self.rcj = None
# 请求对象
self.request_ = None
self.postprocessor_failure = ''
self.postprocessor_failure_message = ''
# 后处理脚本断言结果
self.postprocessor_failure = None
# 后处理脚本错误信息
self.postprocessor_failure_message = None
# 组件期望断言结果
self.expectations_result = False
# cookie数据
self.rcj = None
# http请求字段
self.protocol = None
self.domain = None
self.port = None
self.method = None
self.path = None
self.encoding = None
self.expectation_logic = None
self.message_body = None
self.content_type = None
self.postprocessor = None
self.parameters = None
self.expectations = None
self.file_upload = None
def set_up(self):
super().set_up()
# 获取cookie

View File

@ -21,11 +21,30 @@ class SQLCaseDispatcher(AbstractCaseDispatcher):
:type dispatcher: Dispatcher
"""
super().__init__(case=case, dispatcher_type=dispatcher_type, logger=logger, dispatcher=dispatcher)
# 请求对象
self.request_ = None
self.postprocessor_failure = ''
self.postprocessor_failure_message = ''
# 后处理脚本断言结果
self.postprocessor_failure = None
# 后处理脚本错误信息
self.postprocessor_failure_message = None
# 组件期望断言结果
self.expectations_result = False
# sql请求字段
self.host = None
self.port = None
self.connect_timeout = None
self.user = None
self.password = None
self.db_type = None
self.sql = None
self.charset = None
self.expectation_logic = None
self.postprocessor_script = None
self.expectations = None
def set_up(self):
super().set_up()
# 预处理脚本执行

View File

@ -21,11 +21,29 @@ class SSHCaseDispatcher(AbstractCaseDispatcher):
:type dispatcher: Dispatcher
"""
super().__init__(case=case, dispatcher_type=dispatcher_type, logger=logger, dispatcher=dispatcher)
# 请求对象
self.request_ = None
self.postprocessor_failure = ''
self.postprocessor_failure_message = ''
# 后处理脚本断言结果
self.postprocessor_failure = None
# 后处理脚本错误信息
self.postprocessor_failure_message = None
# 组件期望断言结果
self.expectations_result = False
# ssh请求字段
self.host_name = None
self.port = None
self.connection_timeout = None
self.user_name = None
self.password = None
self.command = None
self.expectation_logic = None
self.method = None
self.postprocessor_script = None
self.expectations = None
def set_up(self):
super().set_up()
# 预处理脚本执行

View File

@ -36,7 +36,28 @@ class AbstractDispatcher(ABC):
:param dispatcher_type: 标识构建是通过单独案例调试(DISPATCHER_TYPE.DEBUG)还是通过模块/项目构建测试(DISPATCHER_TYPE.BUILD)
:type dispatcher_type: str
"""
# 调度数据对象
self.dispatcher = dispatcher
# 调度类型
self.dispatcher_type = dispatcher_type
# 调度日志
self.dispatcher_logger = logger
# 标识触发调度开始的元素
# 对于参与调度的元素默认将触发标志置为False
self.element_is_dispatcher_trigger = False
# 触发调度元素类型 PROJECT or MODULE
self.trigger_element_type = None
# 当前组件类型
self.element_type = None
# 当前组件调度详细数据对象
self.dispatcher_detail = None
# 调试模式直接返回退出__init__
if self.dispatcher_type == DISPATCHER_TYPE.DEBUG:
# 标记当前执行案例所属的project_id执行结束后会删除掉该session
@ -54,40 +75,35 @@ class AbstractDispatcher(ABC):
return
# 下面是对参与调度的元素进行处理
if isinstance(element, Project):
element_type = ELEMENT_TYPE.PROJECT
self.element_type = ELEMENT_TYPE.PROJECT
project_id = element.id
elif isinstance(element, Module):
element_type = ELEMENT_TYPE.MODULE
self.element_type = ELEMENT_TYPE.MODULE
project_id = element.project.id
elif isinstance(element, Scene):
element_type = ELEMENT_TYPE.SCENE
self.element_type = ELEMENT_TYPE.SCENE
project_id = element.module.project.id
elif isinstance(element, Tool):
element_type = ELEMENT_TYPE.TOOL
self.element_type = ELEMENT_TYPE.TOOL
project_id = None # 根据tool.id较难找到其project_id
elif isinstance(element, Case):
element_type = ELEMENT_TYPE.CASE
self.element_type = ELEMENT_TYPE.CASE
project_id = element.scene.module.project.id
elif isinstance(element, LogicController):
element_type = ELEMENT_TYPE.LOGIC_CONTROLLER
self.element_type = ELEMENT_TYPE.LOGIC_CONTROLLER
project_id = None # 根据logic_controller.id较难找到其project_id
else:
raise TypeError('调度构建暂未支持该类型组件element_type=%s' % (type(element)))
# 对于参与调度的元素默认将触发标志置为False
self.element_is_dispatcher_trigger = False
if dispatcher is not None:
self.dispatcher = dispatcher
# 只有调度触发元素会执行下面if语句块内的代码
if (logger is None or dispatcher is None) and element_type in [ELEMENT_TYPE.PROJECT, ELEMENT_TYPE.MODULE]:
if (self.dispatcher_logger is None or self.dispatcher is None) and self.element_type in [ELEMENT_TYPE.PROJECT, ELEMENT_TYPE.MODULE]:
# 标记当前执行案例所属的project_id调度结束后会删除掉该session
# 用于在app.cores.parser.new_parse_data 中方便获取指定项目的变量池
# 定时任务可能存在并发执行的情况而调度任务是在单独的子线程中执行因此即使多个调度任务并发执行对session进行操作互不影响
# 对于debug模式执行时由于Flask本身对于每次请求都是不同线程且不同session因此也不会相互影响
session['project_id'] = project_id
# 标识触发调度开始的元素
self.element_is_dispatcher_trigger = True
# 调度开始元素类型 PROJECT or MODULE
self.trigger_element_type = element_type
self.trigger_element_type = self.element_type
# 如果当前element是触发者通过项目/模块开始构建测试),则创建一条调度数据, 并实例化调度日志dispatcher_logger
self.dispatcher = Dispatcher.add(element_type=self.trigger_element_type, element_id=element.id)
self.dispatcher.update_status(status=DISPATCHER_STATUS.RUNNING)
@ -102,12 +118,10 @@ class AbstractDispatcher(ABC):
emit_dispatcher_start(id=self.dispatcher.id, type=self.trigger_element_type, report_id=report.id)
# 清理http请求的cookie数据
self._clear_http_cookie()
elif logger is not None:
self.dispatcher_logger = logger
# 创建一条调度子数据
if element_type in [ELEMENT_TYPE.PROJECT, ELEMENT_TYPE.MODULE, ELEMENT_TYPE.SCENE]:
if self.element_type in [ELEMENT_TYPE.PROJECT, ELEMENT_TYPE.MODULE, ELEMENT_TYPE.SCENE]:
# 元素类型为Project、Module、Scene时会在构造函数中直接创建调度子数据。而元素类型Case/Tool/LogicController是在Scene.execute()方法中创建
self.dispatcher_detail = DispatcherDetail.add(element_type=element_type, element_id=element.id,
self.dispatcher_detail = DispatcherDetail.add(element_type=self.element_type, element_id=element.id,
element_name=element.name, dispatcher=self.dispatcher)
@abstractmethod
@ -414,15 +428,18 @@ class AbstractCaseDispatcher(AbstractDispatcher, ABC):
:type dispatcher_type: str
"""
super().__init__(element=case, logger=logger, dispatcher=dispatcher, dispatcher_type=dispatcher_type)
# self.dispatcher_type = dispatcher_type
# 日志
if self.dispatcher_type == DISPATCHER_TYPE.DEBUG:
# 对于single_case触发的案例则单独生成构建日志
self.dispatcher_logger = DispatcherLogger(use_memory_string_handler=True, use_queue_handler=False)
self.dispatcher_logger.clear_string_buffer()
self.dispatcher_logger.logger.info('[执行案例开始] ==> [案例名称:%s][案例类型:%s]' % (case.name, case.case_type))
# 案例组件
self.case = case
self.dispatcher_logger.logger.info('[执行案例开始] ==> [案例名称:%s][案例类型:%s]' % (self.case.name, self.case.case_type))
@abstractmethod
def _load_data(self):
"""加载并解析本次案例组件执行需要用到的数据"""
@ -461,6 +478,10 @@ class AbstractToolDispatcher(AbstractDispatcher, ABC):
:type dispatcher_type: str
"""
super().__init__(element=tool, logger=logger, dispatcher=dispatcher, dispatcher_type=dispatcher_type)
# 工具组件
self.tool = tool
# 日志
if self.dispatcher_type == DISPATCHER_TYPE.DEBUG:
# 对于single_case触发的案例则单独生成构建日志
@ -481,13 +502,19 @@ class AbstractToolDispatcher(AbstractDispatcher, ABC):
class AbstractLogicControllerDispatcher(AbstractDispatcher, ABC):
def __init__(self, logic_controller, dispatcher_type=DISPATCHER_TYPE.BUILD, logger=None, dispatcher=None):
def __init__(self, logic_controller, recursive_func, dispatcher_type=DISPATCHER_TYPE.BUILD, logger=None, dispatcher=None):
"""
:param dispatcher_type: 标识构建是通过单独案例调试(DISPATCHER_TYPE.DEBUG)还是通过模块/项目构建测试(DISPATCHER_TYPE.BUILD)
:type dispatcher_type: str
"""
super().__init__(element=logic_controller, logger=logger, dispatcher=dispatcher, dispatcher_type=dispatcher_type)
# 逻辑控制器递归执行函数
self.recursive_func = recursive_func
# 逻辑控制器组件
self.logic_controller = logic_controller
def run(self):
try:
self.set_up()
@ -556,11 +583,14 @@ class ProjectDispatcher(AbstractProjectDispatcher):
def __init__(self, project_id):
project = Project.query.filter_by(id=project_id).first()
super().__init__(element=project, logger=None, dispatcher=None, dispatcher_type=DISPATCHER_TYPE.BUILD)
# 项目组件
self.project = project
self.dispatcher_logger.logger.info(('+'*20 + ' [项目测试开始] ==> [项目名称:%s] ' + '+'*20) % self.project.name)
def set_up(self):
pass
super().set_up()
def execute(self):
# 获取到当前项目下所有模块数据)
@ -582,11 +612,14 @@ class ModuleDispatcher(AbstractModuleDispatcher):
def __init__(self, module_id, logger=None, dispatcher=None, dispatcher_type=None):
module = Module.query.filter_by(id=module_id).first()
super().__init__(element=module, logger=logger, dispatcher=dispatcher, dispatcher_type=dispatcher_type)
# 模块组件
self.module = module
self.dispatcher_logger.logger.info(('='*15 + ' [模块测试开始] ==> [模块名称:%s] ' + '='*15) % self.module.name)
def set_up(self):
pass
super().set_up()
def execute(self):
# 获取到当前模块下所有场景数据)
@ -607,13 +640,18 @@ class ModuleDispatcher(AbstractModuleDispatcher):
class SceneDispatcher(AbstractSceneDispatcher):
def __init__(self, scene, logger=None, dispatcher=None, dispatcher_type=None):
super().__init__(element=scene, logger=logger, dispatcher=dispatcher, dispatcher_type=dispatcher_type)
# 场景组件
self.scene = scene
self.dispatcher_logger.logger.info(('#'*5 + ' [场景测试开始] ==> [场景名称:%s] ' + '#'*5) % self.scene.name)
# 是否发生异常时终止执行
self.stop_on_error = self.scene.module.project.project_advanced_configuration.stop_on_error
# 标识组件执行结果
self.element_execute_result = ''
self.dispatcher_logger.logger.info(('#'*5 + ' [场景测试开始] ==> [场景名称:%s] ' + '#'*5) % self.scene.name)
@contextlib.contextmanager
def _element_execute_context(self):
"""
@ -645,7 +683,7 @@ class SceneDispatcher(AbstractSceneDispatcher):
pass
def set_up(self):
pass
super().set_up()
def execute(self):
# 场景控制器直接执行该控制器下所有组件

View File

@ -9,10 +9,8 @@ from app.cores.logic_controller.logic_controller import (exec_simple_controller,
class SimpleControllerDispatcher(AbstractLogicControllerDispatcher):
def __init__(self, logic_controller, recursive_func, dispatcher_type=DISPATCHER_TYPE.BUILD, logger=None,
dispatcher=None):
super().__init__(logic_controller=logic_controller, logger=logger, dispatcher=dispatcher,
dispatcher_type=dispatcher_type)
self.recursive_func = recursive_func
self.logic_controller = logic_controller
super().__init__(logic_controller=logic_controller, recursive_func=recursive_func, logger=logger,
dispatcher=dispatcher, dispatcher_type=dispatcher_type)
def set_up(self):
super().set_up()
@ -32,10 +30,8 @@ class SimpleControllerDispatcher(AbstractLogicControllerDispatcher):
class IfControllerDispatcher(AbstractLogicControllerDispatcher):
def __init__(self, logic_controller, recursive_func, dispatcher_type=DISPATCHER_TYPE.BUILD, logger=None,
dispatcher=None):
super().__init__(logic_controller=logic_controller, logger=logger, dispatcher=dispatcher,
dispatcher_type=dispatcher_type)
self.recursive_func = recursive_func
self.logic_controller = logic_controller
super().__init__(logic_controller=logic_controller, recursive_func=recursive_func, logger=logger,
dispatcher=dispatcher, dispatcher_type=dispatcher_type)
def set_up(self):
super().set_up()
@ -55,10 +51,8 @@ class IfControllerDispatcher(AbstractLogicControllerDispatcher):
class LoopControllerDispatcher(AbstractLogicControllerDispatcher):
def __init__(self, logic_controller, recursive_func, dispatcher_type=DISPATCHER_TYPE.BUILD, logger=None,
dispatcher=None):
super().__init__(logic_controller=logic_controller, logger=logger, dispatcher=dispatcher,
dispatcher_type=dispatcher_type)
self.recursive_func = recursive_func
self.logic_controller = logic_controller
super().__init__(logic_controller=logic_controller, recursive_func=recursive_func, logger=logger,
dispatcher=dispatcher, dispatcher_type=dispatcher_type)
def set_up(self):
super().set_up()
@ -78,10 +72,8 @@ class LoopControllerDispatcher(AbstractLogicControllerDispatcher):
class WhileControllerDispatcher(AbstractLogicControllerDispatcher):
def __init__(self, logic_controller, recursive_func, dispatcher_type=DISPATCHER_TYPE.BUILD, logger=None,
dispatcher=None):
super().__init__(logic_controller=logic_controller, logger=logger, dispatcher=dispatcher,
dispatcher_type=dispatcher_type)
self.recursive_func = recursive_func
self.logic_controller = logic_controller
super().__init__(logic_controller=logic_controller, recursive_func=recursive_func, logger=logger,
dispatcher=dispatcher, dispatcher_type=dispatcher_type)
def set_up(self):
super().set_up()

View File

@ -20,7 +20,8 @@ class ScriptToolDispatcher(AbstractToolDispatcher):
:type dispatcher: Dispatcher
"""
super().__init__(tool=tool, dispatcher_type=dispatcher_type, logger=logger, dispatcher=dispatcher)
self.tool = tool
# 脚本执行日志
self.log_text = ''
def set_up(self):
@ -53,7 +54,6 @@ class TimerToolDispatcher(AbstractToolDispatcher):
:type dispatcher: Dispatcher
"""
super().__init__(tool=tool, dispatcher_type=dispatcher_type, logger=logger, dispatcher=dispatcher)
self.tool = tool
def set_up(self):
super().set_up()
@ -82,7 +82,6 @@ class VariableDefinitionToolDispatcher(AbstractToolDispatcher):
:type dispatcher: Dispatcher
"""
super().__init__(tool=tool, dispatcher_type=dispatcher_type, logger=logger, dispatcher=dispatcher)
self.tool = tool
def set_up(self):
super().set_up()