跳到主要内容

TestDynamicFlowBase

类插件挂载handler

每个handler负责处理特定type_prefix开头的步骤

    def add_handler(self, handler):
if handler.type_prefix in self.handler_map:
raise Exception("%s is already registered" % handler.type_prefix)

self.handler_map[handler.type_prefix] = handler
handler.setup(self)

比如下面的GeneralCommandHandler用于处理general_开头的步骤

class GeneralCommandHandler(CommandHandlerBase):
def __init__(self, dynamic_flow_base_inst):
super().__init__(dynamic_flow_base_inst)

self.type_prefix = "general_"

模板渲染

case描述文件中有一些动态部分,比如某个步骤是否需要ignore,某个变量的值等,这里负责 通过解析的config及配置的override_map来渲染

我们使用jinja模板文件来描述case,模板的变量定义在配置文件中,比如等待收到期望的响应的最大时长,某个操作的重复次数等,渲染后生成最终的case描述文件。

模板变量替换

有些case步骤基本一样,只是具体配置项不一样,这种我们通过共享case描述文件,然后通过 override_map来对不同case替换不同配置项来做渲染前的预处理

    @staticmethod
def render_config_if_needed(config, render_context=None, dst_path=None, override_map=None):

for orig_value, override_value in override_map.items():

base_str = base_str.replace(orig_value, override_value)

模板具体渲染

    @staticmethod
def render_config_if_needed(config, render_context=None, dst_path=None, override_map=None):

template_library = TemplateLibrary()
template_library.render(base_str, render_context, dst_path)

case运行

执行测试步骤

依次读取渲染后的文件中的每个test step,根据step描述中type的前缀,来找到相应的handler来处理, 比如

    {
"type": "zhiyoufy_environment_get_single_by_name",
"environment_var_path": "environment_var",
"name": "{{ env_name }}",
"must_exist": true,
"step_description": "查找名字为name的environment"
},

zhiyoufy_environment_get_single_by_name的前缀是zhiyoufy_,这个是DynamicFlowZhiyoufyClient这个handler注册处理的,所以会转给它处理

class DynamicFlowZhiyoufyClient:
def __init__(self):

self.type_prefix = "zhiyoufy_"

def process_type_of_zhiyoufy_environment(self, data):

elif data['type'] == 'zhiyoufy_environment_get_single_by_name':
self.process_type_zhiyoufy_environment_get_single_by_name(data)

cleanup

在所有的测试步骤都执行完毕,或者因为某个步骤执行失败导致测试异常结束时,需要做清理,比如资源释放, 清理分两部分,一个是case描述文件中指定的finally部分,一个各个handler自己的cleanup

  • case描述文件中指定的finally部分: 比如有些步骤创建了一些临时资源,可以在finally里检查存在则删除
  • 各个handler自己的cleanup: 通常是更一般的清理,比如账号的logout
    def run(self, test_config, override_map=None):

self.process_finally_node()

for _, handler in self.handler_map.items():
handler.cleanup(self.case_context)