作者:京东物流 刘红妍

导读:在自动化测试实际中,为了更好的符合被测业务场景,须要一直优化框架分层构造。本文联合产品模块化思路,意在介绍通过策略模式革新本来简单分支语句代码,通过实践解说、思路剖析、方案设计、及代码演示,提供自动化脚本重构的落地计划。

01 痛点

在往年的麻利团队建设中,我通过Suite执行器实现了一键自动化单元测试。Juint除了Suite执行器还有哪些执行器呢?由此我的Runner探索之旅开始了!

随着运输业务场景的不断丰富和自动化脚本量的一直累积,日常在review用例时发现,目前大家仍停留在针对需要定制化用例编写,无奈进步用例可复用性和可编排性。当业务流程两头某一环节发生变化时,岂但须要从新批改脚本,还会影响以后利用其余用例执行后果。所以,如何设计高复用性脚本成为目前自动化建设的要害节点。

02  设计实践*

了解,首先 MCube 会根据模板缓存状态判断是否须要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的构造,转换实现后将通过表达式引擎解析表达式并获得正确的值,通过事件解析引擎解析用户自定义事件并实现事件的绑定,实现解析赋值以及事件绑定后进行视图的渲染,最终将指标页面展现到屏幕。从设计稿登程,晋升页面搭建效率,亟需解决的外围问题有:

2.1 设计理念*
      
依据面向对象程序设计理念,设计者应遵循高内聚与低耦合准则,通常程序结构中各模块的内聚水平越高,模块间的耦合水平就越低。高内聚意味着一个类所能提供的性能应该是相干的,即一个类不要设计得包含很多互不相干的性能,低耦合代表要正当布局模块的颗粒度,即要保障一个模块可独立存在,升高模块之间简单依赖关系。

2.2 策略模式**

策略模式定义了一系列的算法,将每一组相干的算法封装起各个策略分支,从而将分支相干的代码暗藏起来,并且使它们之间能够互相替换。策略模式让算法的变动不会影响到应用算法的客户,心愿能够进步程序的可扩展性。

03  解决思路

了解,首先 MCube 会根据模板缓存状态判断是否须要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的构造,转换实现后将通过表达式引擎解析表达式并获得正确的值,通过事件解析引擎解析用户自定义事件并实现事件的绑定,实现解析赋值以及事件绑定后进行视图的渲染,最终将指标页面展现到屏幕。从设计稿登程,晋升页面搭建效率,亟需解决的外围问题有:    

3.1 基本思路

依据运输业务同一个流程存在不同场景,如询价服务接上游下发询价单节点,须要辨别起源执行不同逻辑,目前设计五个算法能力,依据前期业务一直扩大,还会有更多算法退出进来,这个时候须要思考一个好的构造对代码进行优化。可能后期大家通过if...elif...else 分支语句就可实现,但在思考零碎的健壮性和可维护性,这里就不能大量应用if分支语句。因为每一种算法能力的代码量极大且算法参数几十个,在随着更多上游接入可能存在十几个甚至更多else分支,很容易顾此失彼,牵一发而动全身。所以,利用策略模式设计一系列算法,再供用例拼装调用,进步代码的可读性和可复用性。

3.2 计划剖析**

长处:

  1. 代码解耦,便于保护;
  2. 防止应用难以保护的多重条件抉择语句;
  3. 能够运行时动静切换算法;
  4. 开闭准则。毋庸对上下文代码进行批改,就能够增加新的代码。

毛病:

  1. 如果算法逻辑,较为固定,不常常批改,应用策略模式只会减少代码量
  2. 必须晓得所有的具体策略类及它们的区别。

04  计划概述

了解,首先 MCube 会根据模板缓存状态判断是否须要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的构造,转换实现后将通过表达式引擎解析表达式并获得正确的值,通过事件解析引擎解析用户自定义事件并实现事件的绑定,实现解析赋值以及事件绑定后进行视图的渲染,最终将指标页面展现到屏幕。     

4.1 环境依赖

Laputa框架简介:

Laputa框架基于 Pytest 集成了对API接口自动化, 以及对 Web利用, 挪动端利用和 Windows 桌面利用 UI 等自动化的能力。具备可视化的Web界面工具, 便于配置执行规定,关联执行脚本, 触发用例执行,查看执行后果。提供CI集成服务,调用Jenkins API跟踪继续集成后果,凋谢接口,实现流水线自动化测试。

图1 自动化框架架构图

4.2 分层革新**

图2 自动化用例分层图

4.3 策略设计**

图3 策略模式设计图

4.4 操作步骤**

  1. 将频繁批改的算法进行抽取,独立为具体的算法类;
  2. 创立形象基类,实现一个约定的形象策略办法;
  3. 所有独立的算法类,必须实现基类中的形象策略接口;
  4. 建设高低类,该类能够动静的对算法进行setter,创立调用具体算法的办法,上下文可通过该办法与具体的策略交互;
  5. 客户端进行调用,传入具体的算法类,上下文动静执行具体的算法工作。

05  设计实际

了解,首先 MCube 会根据模板缓存状态判断是否须要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的构造,转换实现后将通过表达式引擎解析表达式并获得正确的值,通过事件解析引擎解析用户自定义事件并实现事件的绑定,实现解析赋值以及事件绑定后进行视图的渲染,最终将指标页面展现到屏幕。

5.1 询价接单接口革新

如源代码构造,依据不同业务起源,写在一个办法里通过if...else...别离组装场景,一旦上游任一零碎存在需要变动,以后接单接口调用逻辑须要变动:

【python】def receive_enquiry_bill(**kwargs):params=[{}]params[0].update(kwargs)if params[0].get("enquirySource") == 8:passelif params[0].get("enquiryWay") == 2 and params[0].get("payMode") == 2:passelif params[0].get("enquiryWay") == 2 and params[0].get("payMode") == 3:passif params[0].get("enquirySource") == 46:passif params[0].get("enquirySource") == 20:pass

革新构造:
上下文类

【python】class AlgorithmStrategy(object):    def __init__(self, algorithm_name):                 self.algorithm_name = algorithm_name        @property        def algorithm(self):       return self.algorithm_name      @algorithm.setter       def algorithm(self, name):        self.algorithm_name = name        def execute_algorithm(self, params):        return self.algorithm_name.execute(params)    

算法基类

【python】class CreateEnquiryBillBaseAlgorithm(ABC):# 算法能力基类@abstractmethoddef read_params(self,**kwargs):scenario=kwargs['scenario'] if "scenario" in kwargs and kwargs['scenario'] else 【python】def receive_enquiry_bill(**kwargs):params=[{}]params[0].update(kwargs)if params[0].get("enquirySource") == 8:passelif params[0].get("enquiryWay") == 2 and params[0].get("payMode") == 2:passelif params[0].get("enquiryWay") == 2 and params[0].get("payMode") == 3:passif params[0].get("enquirySource") == 46:passif params[0].get("enquirySource") == 20:pass'base'        return resource_custom_data[self.__class__.__name__][scenario][0].update(kwargs)    @abstractmethod    def execute(self, params):        return jsf_receive_enquiry_bill(data=json.dumps(params)

不同算法:

【python】class CreateTFCEnquiryBill(CreateEnquiryBillBaseAlgorithm):    def read_params(self, **kwargs):        params = super().read_params(**kwargs)        params[0].update({"businessCode": kwargs['businessCode'] if 'businessCode' in kwargs else f"TJ{laputa_util.date_time_str(fmt='%y%m%d')}{laputa_util.get_random_num(8)}","receiveBeginTime": tms_util.data_time_str(minutes=100),"deliveryBeginTime": tms_util.data_time_str(minutes=180)})        return params    def execute(self, params):        return super().execute(params)class CreateECLPClodEnquiryBill(CreateEnquiryBillBaseAlgorithm):      def read_params(self, **kwargs):   # 若以后场景参数与根底参数改变较大倡议间接在Yaml里另写Key   params=super().read_params(**kwargs)   params[0].update({"businessCode": kwargs['businessCode'] if 'businessCode' in kwargs else f"ECO{laputa_util.date_time_str(fmt='%y%m%d')}{laputa_util.get_random_num(8)}","receiveBeginTime": tms_util.data_time_str(minutes=100),"deliveryBeginTime": tms_util.data_time_str(minutes=180)})return params    def execute(self, params):            super().execute(params)return jsf_do_assign(data=json.dumps(params))

算法注入应用:

【python】def receive_enquiry_bill(algOne=None, sceOne=None, **kwargs):    """    Args:        algorithm: 业务类型        scenario:  测试场景:执行步骤,执行数据   Returns:    """ if algorithm:     # 采纳字典模式进行手动注册算法,由python动静查找 st = {"TFC": CreateTFCEnquiryBill(), "ECLP冷链": CreateECLPClodEnquiryBill(), "TC": CreateTCEnquiryBill(),"终端用车": CreateTerminalEnquiryBill()}    query_algorithm = st.get(algOne)    returnquery_algorithm.execute(query_algorithm.read_params(scenario=sceOne, **kwargs)) else: pass

当有需要变动,只需批改其一策略规定外部代码,如【分单策略需要】,除运输外部零碎TFC下发询价指定个体标签,其余上游没有减少标签下发性能,则只需批改CreateTFCEnquiryBill()代码即可。

5.2 Common用例组装

拼接task客户端办法组成case,利用feature组装测试数据,数据驱动测试方法执行。

【python】@pytest.mark.parametrize("params", test_data('test_enquiry_core'), indirect=True)def test_enquiry_core(params):enquiry_code = receive_enquiry_bill_core(**params).get("data")    return quote_enquiry_bill_core(enquiry_code=enquiry_code, **params)

06  总结

了解,首先 MCube 会根据模板缓存状态判断是否须要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的构造,转换实现后将通过表达式引擎解析表达式并获得正确的值,通过事件解析引擎解析用户自定义事件并实现事件的绑定,实现解析赋值以及事件绑定后进行视图的渲染,最终将指标页面展现到屏幕。

随着运输八大产品建设方向逐渐明确,自动化平台须要从利用维度重构到产品维度,在脚本一直交融和解耦过程,如何在新的分层模式设计高复用性脚本,须要大家联合各自业务条线一直优化改良。