• 7、大型项目的接口自动化实践记录----数据分离升级版


    一、常规数据分离

        上一篇,实现了订单新增接口的请求,这块的核心业务case200+,因此要做下数据分离,先提取下方法:

        1、新建resource:订单新增接口.txt,在resource下新建关键字订单新增接口、变量${URI},${URI}值为订单新增接口对应的URI,即/c/contractsign/addcontract


    图1

        2、订单新增接口


    图2

    如上图,提取关键字,后面case数据,只需要维护${port} | ${username} | ${password} | ${data}

    因为登录属于前置条件,因此放到setup中,订单新增接口只保留它自己的内容


    图3

    如下图,改完后,在case层,则只需要维护登录的信息、data


    图4

    PS:登录方法中,在最后需要加,这样case中cookies才可以用


    图5

        因此常规数据分离如下图:


    图6

        完成了数据分离,则开始专注维护测试数据


    图7

        维护下来,发现工作量很大(主要是其中data部分,可见上图滚动条),而且很容易出错。因为其中很多字段关联性强,且有值为json串,如果要保证正确性,则需要通过前端操作,抓包获取数据,这样工作量巨大。以一个case10分钟为例,需要超过2000+分钟,这只是系统的一个模块而已,想想功能要有所变动,增加字段,那维护量就太大了。

    二、数据分离升级版----需要解决的问题

        头脑风暴:每次新功能或者功能变动,都会有对应的手工测试,而手工测试完,在DB中都会留下对应的测试数据。如果可以用特定规则,获取到这些数据,在case层只需要维护如下内容,那么数据的维护工作就很低了。

        数据库名:数据来源库

        数据主键:要取的数据的主键

        端口号:要在哪个环境做接口请求


    图8

        方案思考:

            1、封装对应的数据获取逻辑,根据数据主键、来源库获取对应的数据

            2、处理获取到的数据中的唯一值、特殊值等

            3、最后根据接口字段与DB字段的映射关系,获取到对应的data

        如下图:


    图9

        这样在case层则只需要维护用例、数据主键、来源库,就可以获取到对应的data,手工测试过的数据,就可以快速复用了。

        需要解决:

            1、从DB获取数据

            2、功能对应的数据库表整理

            3、数据获取后,一些字段的值需要修改

            4、接口字段与DB字段的映射

    着手去解决:

    1、从DB获取数据:

        1)先打通数据库


    图10

        在suite文件处,先导入库DatabaseLibrary、Collections、String

        实现连接数据库,查询:


    图11

        ①连接数据库:Connect To Database Using Custom Params

            Driver=对应装的ODBC版本

            Server=数据库地址(一般是数据库服务器IP)

            Port=端口号

            Database=要连接的数据库name

            User=用户名

            Password=密码

        ②查询:Query

        ③打印查询结果:log ${data}


    图12

        可以在日志可以看到成功获取到了数据,数据格式为由元组组成的list:[(),()]

        2)封装对应方法

            ①连接数据库:


    图13

    图14

            假设常用的环境对应的数据库有三个,分别为DB1、DB2、DB3,每个库都有对应的用户名密码等信息,则配置如图10,变量名以num结尾,第一个库的信息为0,第二个为1……。

            连接数据库的方法,根据传入的库名,设置变量${num},然后根据${num}连接对应的数据库。

            ②查询数据:

            上面看到,用Query可以查询到对应的数据,但是格式是元祖组成的list,不太方便后面的使用,如果数据是字段名+value的键值对,即[dict,dict,……],则会比较方便使用,因此我们再做下封装。

                A、首先根据查询语句获取keys(字段名)


    图15

                B、然后根据查询语句获取keys及datas


    图16

                C、再然后keys、values拼接成dict


    图17

    PS:有简单的写法${dict_back} Evaluate dict(zip(${keys},${values})),但是因为我们的数据会有特殊值,该写法会出错,因此没有用。

                D、接着用获取的keys、datas组成dicts_list


    图18

                E、最后根据查询语句,获取数据dict集,拼接成dicts_list


    图19

            好处:后面使用方便

            缺点:性能变差(因此大数据时不使用)

    2、功能对应的数据库表整理

        考虑预发布环境操作的频率会较低,因此在预发布环境开放SQL日志

        然后在linux服务器上,对应的目录下,加一个脚本,内容如下,其中mysql-bin.index为二进制日志汇总

        脚本功能:根据起止时间,过滤出insert、update、delete开头的语句,其中mysql-bin.index为日志汇总,这样用户在预发布环境操作后,可以根据起止时间,过滤出对应的SQL语句


    图20

        为了获取SQL执行语句,还要专门上linux服务器执行命令,这样比较麻烦,因此在RF上去实现下:

        导入SSHLibrary


    图21

        通过SSH连接到linux服务器,入参为起止时间,执行linux服务器上的脚本,更新sqllog文件


    图22

        接着把linux服务器上,对应的sqllog文件下载到本地指定路径

        PS:Get Tables是自己封装的方法,作用是再根据下载下来的文件,过滤出对应的表名并去重。


    图23

    3、修改字段的值

        举个栗子,假设一个单据对应多条明细,单据id为100,我们通过方法”根据查询语句,获取数据dict集,拼接成dicts_list“ + ”SELECT * FROM 明细表  WHERE parentid=100“,查询到结果如下:

        [{u'name': u'test1', u'parentid': u'100'}, {u'name': u'test2', u'parentid': u'100'}]

        其中parentid为明细对应的主表id,我们在RF这边模拟构造下这个数据


    图24

    图25

        当我们从DB获取到主表及明细表的数据,当做测试数据使用时,那么会发现,新增主表数据的时候,有新id生成,假设为101,那么新增明细的时候,对应的parentid需要改成101。可以通过for循环遍历list,把其中的parentid改掉,如下图。


    图26

        结果如下,可以看到parentid都变成101了。


    图27

    4、接口字段与DB字段的映射


    图28

        映射关系如上图,其中${data_all}、${current_data_all}为前面dicts_list中的dict,因此如${data_all['id']}可以取到对应的id值,传给接口的id字段。

    三、数据分离升级版----订单接口实现

        我们以逆推的方式,去看这个过程实现

        1、首先新建合同和订单新签目录,在目录下新建DB与接口映射关系Resource,在该Resource下,放图9中的func3,根据映射关系、数据,获取data。

            1)在Resource下新建方法,获取cdn订单新增data。


    图29

            方法内容如下,新建${data},把接口抓到的所需要的入参都add上。


    图30

            2)观察字段来源于哪张表的字段,发现分别来源于contract、paycls、pay表,还有些特殊字段如cdnitemjson,它的值是一个json串,相当于子data串,因为这层做的是data这层的映射,因此先不管它。

            假设我们已经取到了对应几张表的data及几个json串,并且已经处理过,则映射关系如下图:


    图31

            3)同样的,新建获取对应的appditemjson、cdnitemjson、speedjson


    图32

            与主data不一样的是,这些json串,数量可能为0~N,因此入参为dicts_list,映射关系写法如下图,在for循环中做对应的赋值(这里只写两个字段做下说明)。


    图33

        2、新建Resource:DATA_来源,在下面放图9中的func1,用于从DB获取数据

            1)新建方法,获取对应的数据


    图34

                2)因为我们要查的数据不多,因此直接用了select *,主data信息都是一条,返回的是dict,所以返回list[0]


    图35

            对应的json串数据,数据可能性0~N条,因此返回dicts_list


    图36

        3、新建Resource:DATA_处理,在下面放图9中的func2,前面获取到的数据,还不能直接使用,需要对其中的一些特殊字段进行处理。

            1)新建方法,处理对应的数据


    图37

            2)下图为json的字段处理举例,其中接口请求中字段为id,但是DB中则不是,act字段为固定值,有的字段可能会是随机数等。


    图38

        4、新建Resource:操作步骤_DATA,引用前面3个Resource


    图39

            1)在目录下,新建方法订单新增data,实现获取、处理、映射成接口可用data的过程


    图40

            2)方法内容如下,将前面的过程串联起来,发现我们只需要传数据主键,就可以获取到对应的data了。


    图41

    图42

        5、再跟前面的Action等关联上,新建Resource:操作步骤,引用操作步骤_DATA。


    图43

    图44

            1)新增方法订单新增,即操作步骤的ACTION


    图45

        6、新建Resource:订单新增FLOW,引用”操作步骤“


    图46

    图47

            1)新增方法订单新增FLOW,连接数据库,执行操作步骤,实际结果与预期结果对比


    图48

        7、再新建suite,引用订单新增FLOW,在suite下新建case,则实现了图8中所期望的。

    上一篇  6、大型项目的接口自动化实践记录----订单新增

    下一篇  8、大型项目的接口自动化实践记录----DB分别获取预期结果、实际结果

  • 相关阅读:
    Mac-安装Git以及Git的配置
    Mac 安装Maven,并设置环境变量
    Mac Tab自动补全键
    Eclipse 代码快捷键模板(一)
    网易博客迁移(2011-05-27)
    前端JS插件整理
    Ajax请求二进制流并在页面展示
    IDE中使用System.getProperty()获取一些属性
    Spring Boot:快速入门(二)
    c 语言 指针 与地址
  • 原文地址:https://www.cnblogs.com/walkingtester/p/11280703.html
Copyright © 2020-2023  润新知