加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

接口自动化项目实践

发布时间:2020-12-14 04:44:18 所属栏目:百科 来源:网络整理
导读:先说结论。 覆盖接口:300个。 覆盖模块:12个,其中二级模块47个。 开发模式下,调用接口次数: 6828 次,脚本运行耗时 1h18min3s 。 上线模式下,调用接口次数: 1257 次,脚本运行耗时 15min46s 。 该系统已稳定运行,本次测试过程中,发现了4个隐藏bug。

先说结论。

覆盖接口:300个。

覆盖模块:12个,其中二级模块47个。

开发模式下,调用接口次数:6828次,脚本运行耗时1h18min3s

上线模式下,调用接口次数:1257次,脚本运行耗时15min46s

该系统已稳定运行,本次测试过程中,发现了4个隐藏bug。

此次实践是基于前面分享的几篇博文进行的。

Name Content
测试框架 接口自动化测试框架-AIM
测试思想 结对测试vs随机测试parewise算法性能优化(用例设计层面)
接口工具 F12开发者工具,Postman,Fiddler

编码的难点在于如何总结出各模块各接口的规律,

以尽量简化的代码,尽可能地覆盖更多的场景。

举个例子,下面这两段代码,就是在摸索出代码参数规律后写出来的。

eg1:

        productList = [("1","3",sample(["5","6","7","8"],2)),("1","4",["9","10"]),"5",sample(["11","12","13"],["14","15"]),("2",["16","17"])]
        for product in productList:
            for monitorLevel in ("1","2","3"):
                self.req({
                    "url": full_url("xxx"),"body": {"xxx": monitorLevel,"xxx": "3","xxx": product[0],"xxx": product[1],"xxx": product[2]}
                })

eg2:

    def test_portrait(self):
        # xxx
        table = [("1","xxx"),# xxx
                 ("2",# xxx
                 ("3",# xxx
                 ("4",# xxx
                 ("5",# xxx
                 ("6",# xxx
                 ("7",# xxx
                 ("8","xxx")]  # xxx
        data = list()
        for t in table:
            field = [x['COLUMN_NAME'] for x in
                     dao.select_dict('''select * from information_schema.COLUMNS t where table_name='%s';''' % t[1])
                     if x['COLUMN_NAME'] not in ['xxx','xxx']]
            data.append({"xxx": t[0],"field_name": field})
        self.req({
            "url": full_url("xxx"),"body": {"xxx": pub.xxx(1)[0],"data": data}
        })

参数是接口测试最核心的部分,怎么处理就决定了接口测试的效率。

1、单选/多选

单选

"quarter": ("3","6")

多选

checkbox("1,2,3,4,6,5")

checkbox是对多选项参数进行了处理:

def checkbox(option,j=None):
    """
    :param option:
    :param j: 组装参数的方式 list无 str默认',' 可以指定
    :return:
    """
    if j is not None:
        if isinstance(option,str):
            option = option.split(j)
        return j.join(option),j.join(sample(option,random.randint(1,len(option) - 1)))
    if j is None:
        if isinstance(option,str):
            j = ','
            option = option.split(j)
            return j.join(option),len(option) - 1)))
        if isinstance(option,list):
            return option,sample(option,len(option) - 1))

兼顾了“1,3”和[1,3]两种组装参数的方式。

2、相互联动的参数

也就是说参数a的变化联动改变参数b。

一种方式是构建元组List,循环遍历

tz_zjbd = [(checkbox("xxx"),""),# xxx
                   ("",checkbox("xxx"))]  # xxx
        tz_qixian = [(checkbox("1,5,6"),"",("","0","500")]  # xxx
        relate = [(tz_zjbd[0],tz_qixian[0]),(tz_zjbd[1],tz_qixian[1])]
        pw = list()
        for rel in relate:
            p = {
                "url": None,"body": {
                    "content": [
                        {
                            "xxx": "2018-01-01","xxx": date("2018-01-01","2019-03-01"),"xxx": "2018-01-01","xxx": checkbox("xxx"),"xxx": "0","xxx": "100","xxx": checkbox("1,2"),7"),"xxx": "","xxx": rel[1][0],3"),"xxx": ','.join(pub.bankName(3)),"xxx": "理财","xxx": rel[1][1],"xxx": rel[1][2],'.join(pub.cityName(5)),"xxx": rel[0][0],"xxx": rel[0][1],"xxx": "1","xxx": "asc"
                        }
                    ]
                }
            }
            pw = pw + parewise(p['body']["content"][0])

一种方式是拆开分别处理

p = {
            "url": full_url("xxx"),"body": {
                "xxx": checkbox("1,5"),"xxx": date('2018-01-01','2018-05-01'),"xxx": date('2018-05-02','2019-01-01'),"xxx": ("1","2"),"xxx": ("area_ch","all_ch"),"2")}
        }
        for x in parewise(p['body']):
            p['body'] = x
            self.req(p)
        area_list = sample(
            """'海南省','安徽省','福建省','江西省','山东省','河南省','湖北省','湖南省','广东省','上海','广西壮族自治区','四川省','贵州省','云南省','西藏自治区','陕西省','山西省','甘肃省','青海省','宁夏回族自治区','新疆维吾尔自治区','天津','重庆','内蒙古自治区','辽宁省','吉林省','黑龙江省','江苏省','北京','河北省','浙江省'""".split(','),20)
        p = {  # 省份
            "url": full_url("xxx"),"reports_type": ("1","xxx": "province_ch","xxx": checkbox(area_list,","),"2")}
        }
        for x in parewise(p['body']):
            p['body'] = x
            self.req(p)

视情况怎么方便怎么来。

3、接口依赖

接口的参数需要从另外接口的返回数据获取。

r = self.req({
            "url": full_url("xxx"),"body": {}
        })
        for content in r.json()['content']:
            for indexList in content['indexList']:
                self.req({
                    "url": full_url("xxx"),"body": {
                        "indexCode": indexList['indexCode'],"searchDate": "year1"
                    }
                })

4、从数据库取测试数据

        s = dao.select_dict("""SELECT * FROM xxx""")
        p = {
            "url": full_url(url),"body": {
                "page": 1,"pageSize": 15,"xxx": tuple(sample([x['doc_issuing_agency'] for x in s],"xxx": tuple(sample([x['doc_name'] for x in s],"xxx": tuple(sample([x['post_no'] for x in s],"xxx": tuple(sample([date2str(x['publish_date']) for x in s],"xxx": ""
            }
        }
        for x in parewise(p['body']):
            p['body'] = x
            self.req(p)

5、请求超时的问题,可以参阅这篇频繁请求报requests异常的处理

6、判断flag

最初的方案是每个接口返回flag不一样,在每个接口返回后,在用例中通过将flag和响应,传参给封装函数做判断。

最新的方案是综合所有接口返回结果,在req函数统一判断。用例中不再判断。

    def checkFlag(self,p,r):
        """预期,实际"""
        err = str([p['url'],p['body'],r.text])
        try:
            b = False
            if (r.json()['flag'] in [1,'1','',None,'statistic_by_result','struct_product','v_select_jz_single']
                    or r.json()['message'] in ("暂无数据","未查询到数据")):
                b = True
            self.assertEqual(True,b,msg=err)
        except (json.JSONDecodeError,KeyError):  # 1.返回的不是json,比如下载、404  2.无flag
            self.assertEqual(200,r.status_code,msg=err)

说一下心得体会。

做demo和做真实项目完全是两回事。

快捷键是真好用,尤其是代码写多了之后。(虽然写的还不多,但快捷键是真滴)

性能很重要,该优化的要想办法及时优化,哪怕修改实现方式。

码代码前,就算封装一个函数,也要多思考设计,想清楚了再行动,不然挨个挨个重新改一遍真的五味杂陈。

编码效率>框架体验。这是加了用例执行进度1/100这种又去掉之后的感悟。没有必要纠结可有可无的细小体验添加冗余代码。

版权申明:本文为博主原创文章,转载请保留原文链接及作者。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读