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分别获取预期结果、实际结果

posted on 2019-08-01 09:49  慢慢走的测试  阅读(552)  评论(0编辑  收藏  举报