作者:京东物流 刘红妍

导读:

在主动化测试实践中,为了更好的契合被测事务场景,需求不断优化结构分层结构。本文结合产品模块化思路,意在介绍经过战略方式改造原本杂乱分支句子代码,经过理论讲解、思路剖析、计划规划、及代码演示,供给主动化脚本重构的落地计划。

在本年的灵敏团队建造中,我经过Suite履行器完结了一键主动化单元测试。Juint除了Suite履行器还有哪些履行器呢?由此我的Runner探索之旅开端了!

1 痛点

跟着运送事务场景的不断丰富和主动化脚本量的不断累积,日常在review用例时发现,现在大家仍停留在针对需求定制化用例编写,无法进步用例可复用性和可编列性。当事务流程中间某一环节发生变化时,不但需求重新修正脚本,还会影响当前使用其他用例履行成果。所以,如何规划高复用性脚本成为现在主动化建造的关键节点。

规划理论

了解,首要 MCube 会根据模板缓存状况判别是否需求网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产品转化为视图树的结构,转化完结后将经过表达式引擎解析表达式并获得正确的值,经过事情解析引擎解析用户自定义事情并完结事情的绑定,完结解析赋值以及事情绑定后进行视图的烘托,最终将方针页面展现到屏幕。从规划稿动身,进步页面搭建功率,亟需解决的核心问题有:

2.1 规划理念

根据面向对象程序规划理念,规划者应遵从高内聚与低耦合准则,一般程序结构中各模块的内聚程度越高,模块间的耦合程度就越低。高内聚意味着一个类所能供给的功用应该是相关的,即一个类不要规划得包括很多互不相干的功用,低耦合代表要合理规划模块的颗粒度,即要保证一个模块可独立存在,降低模块之间杂乱依靠关系。

2.2 战略方式

战略方式定义了一系列的算法,将每一组相关的算法封装起各个战略分支,从而将分支相关的代码躲藏起来,而且使它们之间能够相互替换。战略方式让算法的变化不会影响到运用算法的客户,期望能够进步程序的可扩展性。

解决思路

了解,首要 MCube 会根据模板缓存状况判别是否需求网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产品转化为视图树的结构,转化完结后将经过表达式引擎解析表达式并获得正确的值,经过事情解析引擎解析用户自定义事情并完结事情的绑定,完结解析赋值以及事情绑定后进行视图的烘托,最终将方针页面展现到屏幕。从规划稿动身,进步页面搭建功率,亟需解决的核心问题有:

3.1 基本思路

根据运送事务同一个流程存在不同场景,如询价服务接上游下发询价单节点,需求区分来历履行不同逻辑,现在规划五个算法才能,根据后期事务不断扩展,还会有更多算法加入进来,这个时分需求考虑一个好的结构对代码进行优化。或许前期大家经过if…elif…else 分支句子就可完结,但在考虑体系的健壮性和可保护性,这里就不能很多运用if分支句子。因为每一种算法才能的代码量极大且算法参数几十个,在跟着更多上游接入或许存在十几个乃至更多else分支,很简单顾此失彼,牵一发而动全身。所以,运用战略方式规划一系列算法,再供用例拼装调用,进步代码的可读性和可复用性。

3.2 计划剖析

长处:

  1. 代码解耦,便于保护;

  2. 防止运用难以保护的多重条件选择句子;

  3. 能够运行时动态切换算法;

  4. 开闭准则。无须对上下文代码进行修正,就能够添加新的代码。

缺点:

  1. 如果算法逻辑,较为固定,不常常修正,运用战略方式只会添加代码量

  2. 必须知道所有的详细战略类及它们的区别。

计划概述

了解,首要 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.创建笼统基类,完结一个约好的笼统战略办法;

  1. 所有独立的算法类,必须完结基类中的笼统战略接口;

  2. 树立上下类,该类能够动态的对算法进行setter,创建调用详细算法的办法,上下文可经过该办法与详细的战略交互;

  3. 客户端进行调用,传入详细的算法类,上下文动态履行详细的算法使命。

规划实践

了解,首要 MCube 会根据模板缓存状况判别是否需求网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产品转化为视图树的结构,转化完结后将经过表达式引擎解析表达式并获得正确的值,经过事情解析引擎解析用户自定义事情并完结事情的绑定,完结解析赋值以及事情绑定后进行视图的烘托,最终将方针页面展现到屏幕。

5.1 询价接单接口改造

源代码结构,根据不同事务来历,写在一个办法里经过if…else…分别拼装场景,一旦上游任一体系存在需求变化,当前接单接口调用逻辑需求变化:

【python】
def receive_enquiry_bill(**kwargs):
params=[{}]
params[0].update(kwargs)
if params[0].get("enquirySource") == 8:
pass
elif params[0].get("enquiryWay") == 2 and params[0].get("payMode") == 2:
pass
elif params[0].get("enquiryWay") == 2 and params[0].get("payMode") == 3:
pass
if params[0].get("enquirySource") == 46:
pass
if 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):# 算法才能基类
    @abstractmethod
    def read_params(self, **kwargs):
scenario=kwargs['scenario'] if "scenario" in kwargs and kwargs['scenario'] else '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)
    return query_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)

总结

了解,首要 MCube 会根据模板缓存状况判别是否需求网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产品转化为视图树的结构,转化完结后将经过表达式引擎解析表达式并获得正确的值,经过事情解析引擎解析用户自定义事情并完结事情的绑定,完结解析赋值以及事情绑定后进行视图的烘托,最终将方针页面展现到屏幕。

跟着运送八大产品建造方向逐渐清晰,主动化渠道需求从使用维度重构到产品维度,在脚本不断融合宽和耦过程,如何在新的分层方式规划高复用性脚本,需求大家结合各自事务条线不断优化改进。