前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >接口测试平台代码实现52: 自动异常测试-5

接口测试平台代码实现52: 自动异常测试-5

作者头像
我去热饭
发布2022-05-19 09:05:40
7700
发布2022-05-19 09:05:40
举报
文章被收录于专栏:测试开发干货

打开我们上次没写完的P_apis.htm

找到这个error_play函数,我们已经替换好了请求体,那么接下来就把新请求体和接口id传递给后台即可

在以下俩个位置加上对应传递后台的代码:

我们把接口id和新请求体传给后台。所以去写urls.py:

然后去写views.py:

这个函数的功能就是实际发出请求获取请求体,再把请求体返回给前端了。

整个代码和我们调试层传递的类似。但是调试层发送请求的函数的所有接口数据都是从前端获取。而异常值发送请求函数的所有接口数据基本是靠着接口id从数据库获取,然后请求体用前端传过来的新请求体:

代码如下:

代码语言:javascript
复制
# 异常值发送请求
def error_request(request):
    api_id = request.GET['api_id']
    new_body = request.GET['new_body']
    api = DB_apis.objects.filter(id=api_id)[0]
    method = api.api_method
    url = api.api_url
    host = api.api_host
    header = api.api_header
    body_method = api.body_method
    header = json.loads(header)
    if host[-1] == '/' and url[0] =='/': #都有/
        url = host[:-1] + url
    elif host[-1] != '/' and url[0] !='/': #都没有/
        url = host+ '/' + url
    else: #肯定有一个有/
        url = host + url
    if body_method == 'form-data':
        files = []
        payload = {}
        for i in eval(new_body):
            payload[i[0]] = i[1]
        response = requests.request(method.upper(), url, headers=header, data=payload, files=files)
    elif body_method == 'x-www-form-urlencoded':
        header['Content-Type'] = 'application/x-www-form-urlencoded'
        payload = {}
        for i in eval(new_body):
            payload[i[0]] = i[1]
        response = requests.request(method.upper(), url, headers=header, data=payload)
    elif body_method == 'Json':
        header['Content-Type'] = 'text/plain'
        response = requests.request(method.upper(), url, headers=header, data=new_body.encode('utf-8'))
    else:
        return HttpResponse('非法的请求体类型')
    # 把返回值传递给前端页面
    response.encoding = "utf-8"
    return HttpResponse(response.text)

当然我现在不知道这个接口是否存在bug,在未进行测试的前提下,没人能保证没问题。

所以我们加入点print,来看看有没有问题,因为咱手里现在也没有能正常访问的接口。大家看看请求体没问题就可以了:

当然前端页面我们上节就证明没问题了:

后端加入:

开始测试:

经过测试,发现出现了问题。这个问题的情况就是后台没有成功获取到替换后的请求体,我们可以理解为,这个传输过程发生了错误或传输成功,但是后台解析不了。

那么具体什么错误呢?前端明明可以正常发出去,为啥后台就解析不了呢?

原因是请求体中的二维数组无法直接传递,必须变成字符串。包括我们常见的json,其实都是json格式的字符串而已。只能等到后台接收到之后,再用eval来进行还原成二维数组或字符串了。

所以前端我们要进行变换:

然后我们再测试看看后台输出:

可以看到,虽然输出的并不完善,但是起码解析出来了。

我们忽略掉 这个请求根本没有返回值的报错:(因为url都是随便写,我们可以之后用自己公司的实际接口测试,但是要注意,这个请求频率非常快,接近并发,请不要随意尝试,一瞬间几百个请求出去,你们服务器可能会报警...)

这里我们发现了一个bug,就是我们貌似所有的替换值 都变成了字符串?明明我们要测试的场景里还有整形等。

其实是因为我们之前在js中进行替换的时候,全部当成字符串替换,其实应该替换的是忠实的原始用户需求格式,也就是我们需要对其进行求值再替换:所以这里变成eval()

然后我们开始测试raw-json的格式替换了:

代码中加上我们之前的俩处修正:

点击开始测试,看看前端console.log的输出如何:

看起来没啥问题,后台输出也可以正常获取解析新请求体:

接下来就要开始这个功能的最后一个部分了。

那就是返回值的显示效果。当然我们现在接口都请求不通,也就没有返回值。那么没返回值的情况怎么办呢?我们也不能等着服务器后台报错。所以这里请求我们加上一个try来捕获吧。

一个简单的方法是把下面的整个大请求代码段都try了。

然后测试发现不报错了。

然后我们前端其实此时已经成功拿到了返回值,虽然返回值现在都是“对不起,接口未通!” 我们就来做一下动态生成html代码,来看看最终效果,之后我们有机会再找个可以请求通的接口来测试。

再次打开P_apis.html

我们本应该在这俩个请求的返回函数中 都写上这段动态生成的代码,但是考虑到代码量应该不少,所以我们最好是新建一个js函数,专门负责展示。然后在这俩个返回函数中调用它即可:

声明了一个error_show_response后,在下面俩处进行调用:

我们把返回值ret 作为参数传递貌似不够,因为我们还要知道这个ret对应的替换规则是什么。

所以我们这里要进行替换规则这个字符串的构造:

这个span_text 就是我们的替换标题

接下来给error_show_response(ret) 加上这个参数:

之后我们把注意力全部放在这个error_show_response(span_text,ret)里吧:

我们现在分析下,我们已经拿到了返回体。那么就应该新建一个多行文本框或者来显示就好了,格式就和我们最开始的demo一样,demo等我们写完代码后就删除了。

所以代码如下:

代码语言:javascript
复制
    function error_show_response(span_text,ret) {
        var error_div = document.getElementById('error_div'); // 声明这个请求体展示窗口
        var s = document.createElement('span'); //创造替换标题
        s.innerText = span_text;

        var t = document.createElement('textarea'); //传教替换内容多行文本
        t.style = 'width: 99%;height: 50px;border-radius: 5px;color: black;margin-bottom: 10px';
        t.value = ret;

        error_div.appendChild(s);
        error_div.appendChild(t);
    }

然后进行测试,发现结果如下:

貌似全部展示成功了。但是仔细观察却发现了一个超大的bug,就是所有的替换标题文案 ,都一样...

那么这里问题出在哪了呢?

我们只能在各个位置,打印这些文案,看看究竟出在哪了

如上图,我们在最小的这个循环体内,俩个位置分别打印了这个span_text,并且前面加上了标记 1 和2 然后看看最终效果

这里我们发现,是因为2开头的时候,输出的貌似都出了问题。那么这个原因我们可以来猜测一下:

首先奇怪的是,明明12次循环,为啥下面的2开头输出,会在最后位置输出?

还有就是,为啥显示的都是12次循环最后一次的值 b-->中文 ?

聪明的同学已经知道原因所在了,就是这个js循环的执行顺序是 12次循环先执行完,发出去请求就不管了,并不会等到第一次请求返回,再开始第二次循环。

简单来说,就是12次请求 先执行完,过了一会,12次请求的返回体才陆续到位,而这时span_text这个变量早已被12次请求的最后一次b-->中文赋值了。

所以显示的都是这最后一个值。

那么这个问题我们要怎么解决呢?

这里提供几种思路:

  1. 在变量上下手,防止变量的值被覆盖,每次的变量名都不同。
  2. 锁死循环,必须等待前一次接收到返回体后再开始第二次循环。

3. 在变量上想办法,做一个变量标题数组,存入所有标题,当调用的时候再依次提取。

4. 在发出请求的时候,带上这个替换标题,再原封不动的返回。

其实这个现象很好比喻:

就像你有12门火炮。 你可以按顺序,依次发射。但是你无法预测和决定炮弹落地的顺序。然后你要炮弹落地后,根据现场混乱的弹坑,来分辨出都是哪门火炮炸的,这显然很困难。

所以我们在上述四个方案中,选择最简单的,第四种。让炮弹发射出去的时候,贴上标签。落地后标签掉在弹坑里,你就自然能分清了。

后台函数:

那么后台我们之前每次返回基本都是只返回一个字符串,也就是一般只返回一个参数字段。那么我们现在要返回的是俩个。要怎么做呢?

你可以进行字符串拼接,然后前端拿到后再给分割开。

你也可以标准一点,做一个json串来加入,前端再进行解析即可。

我们采用标准方法,所以返回代码这么写:

然后前端接收到之后 这么解析:

重启服务,刷新页面,开始测试:

发现其实效果已经不错了,没有出现对不上号的情况,我们把对应的修改 给放入到上面的二维数组中吧:

放好后,我们修改接口的请求体类型为form-data,来测试一下:

发现仍然可以成功。

但是最后我们仍然留下了一个小问题,就是貌似他们的显示顺序并不是一开始我们排好的预期的。这是因为各个请求体的返回速度不同,先回来的就先抢到了位置了。其实这并不影响实际使用,实际使用中,基本是几百个请求返回体,没人关注他们的摆放顺序,基本就是大致扫一眼,看看没有服务器严重报错的情况就结束测试了。发现有引起服务器报错的,就看一下替换标题记录下来就可以了。

最后别忘了删除那个demo:

然后最后就要解决一下我们上节遗留的bug了

就是请求体raw-json格式带换行的情况下,打开报错怎么处理。

发生问题的原因,在于我们html代码中,调用error_test时,按钮的html代码因为换行导致了浏览器解析它失败。

解决方案有很多。其实严格来说,一般区区一个按钮内的onclick要传这么大量的数据,本就不是一个好办法。万一数据中含有一些引号,双引号,括号,<>等 其实相当于 破坏了html结构,属于一种变异的病毒攻击常用手段。 换行符只是其中一种引起报错的情况,即便我们解决了换行符,后面也许还会经常互相各种特殊符合引起的html结构错乱的报错。

所以我们这里最好放弃这么直接传输,那么我们可能马上就想到,通过其他拐弯抹角的方式 把这个值传给error_play。但是其实进入页面的时候,我们给的接口数据,只是给了html。js没有办法直接获得,只能张嘴等html传给它,或者html里用比如input记录下,然后js根据接口id去提取。

所以这里公布俩种解决方案:

  1. 每个接口下设置一个隐藏的input。input的id是动态的,内部的value值就寸这个接口的请求体(带换行的原封不动的)
  2. 进入接口库的后台函数,不只给html传递接口数据,也同时给js传一个接口数据,这样js就可以根据接口id 去自己专用的数据中找到接口的请求体了。

我们选用第一种简单方式。

先加入隐藏的input :

注意这个input我开始没有隐藏,和放入的位置。看看页面显示效果:

值是成功存储的,再看看动态id:

然后我们给它隐藏:

现在去掉我们之前旧的传输参数

给error_test 加入自己提取api_body的代码:

然后再来测试下,我们之前打开报错的带换行情况的接口:

发现已经可以成功打开并且开启异常测试了!

好了,异常测试的章节 暂时告一段落了。后续我们还会进行优化和功能添加。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试开发干货 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档