接口测试平台代码实现72: 多接口用例-12

129 阅读6分钟

在本节开始之前,我们在先要解决之前遗留的那个第三方table导致的一个bug:

就是多重列:

图片

我们之前接口库中的解决方案是刷新页面绕过这个恶心的问题,但是步骤这里貌似不太适合刷新整个页面。所以只能面对。引起这个问题的原因是我们初始化这个表的时候,只初始化了tbody也就是内容部分,没有初始化thead表头部分.

所以我们给这俩个表的表头加上id,以便控制:(直接ctrl+F 搜索找到准确位置)

图片

然后在我们的初始化清空步骤详情页的函数中加上这么几句:

图片

红色圈部分代码:

document.getElementById('mythead').innerHTML='  <tr>\n' +
            '                        <td style="width: 30%">Key</td>\n' +
            '                        <td style="width: 50%">Value</td>\n' +
            '                      </tr>';
        document.getElementById('mythead2').innerHTML='  <tr>\n' +
            '                        <td style="width: 30%">Key</td>\n' +
            '                        <td style="width: 50%">Value</td>\n' +
            '                      </tr>';

现在这个多重列的问题就解决了。

让我们先看一看还剩下的任务:

4.步骤详情页的提取返回值功能

    5.步骤详情页的断言返回值功能

7.步骤选择仓库接口生效

    8.步骤的执行序号生效

    9.用例实际执行的后台实现

    10.报告的生成和保存

    11.报告的展示

    12.报告的word导出

    13.步骤的mock功能

本节我们准备搞定 选择接口仓库接口的功能:

也就是说,我们在套用接口库已经经过单接口调试的接口。

我们之前做了这个下拉选框:

图片

当我们选择具体内容后,期望下面的各项输入框都跟着变:

那就先找到这个选框的html源码:

图片

注意,我们的id是apis。

然后我们要写一个监听类的js函数,监听这个select,只要内容变化,就触发下函数:

图片

在红框内 ,我们要开始写上触发的动作代码了。

这里我们触发后,唯一能获取到的就是这个select的value,就是最新选中的option的值:

图片

这个值,也就是选中的接口库中接口的id。

我们拿到这个id,就可以跟后台找到这个接口的所有数据,然后填充到步骤详情页下面的各个输入框中,但是在这之前,我们要先清空一下这个步骤详情页内容,以免旧数据影响(但是我们的清空初始化步骤详情页的函数里,对这个select本身也进行了初始化,这就导致无论我们选什么接口,都会变成一开始的none,导致代码无法继续运行。联想到我们的接口执行序号/名称/显示id等也都被删除了,所以我们打算重写一个这里专用的初始化函数)。

所以代码如下:后面有完整该函数代码可复制。

图片

上图中,增加了一层if判断,如果选的不是那个第一个值none才开始触发后续。

然后我们去写urls.py:

图片

然后去views.py:

图片

最后我们回到前端js,解析这个返回值,先输出一下看看对不对,

重启服务,刷新页面,试一下:

图片

看来是成功了,每次选不同的接口,都可以打印出来这个接口最新的数据。

然后就是填充,关于填充的函数,我们也写过,就是打开步骤详情页时候运行的那段,我们直接复制过来,改一改成如下(注意,步骤名称和执行顺序不要改动)

图片

整个函数的完整代码如下:

<script>
     $(document).ready(function () {
        $("#apis").change(function () {
            //这里写只要触发后要执行的代码,就是把下面输入框全部填充的代码
            document.getElementById('step_method').value = 'none';
            document.getElementById('step_url').value = '';
            document.getElementById('step_host').value = '';
            document.getElementById('step_header').value='{}';
            // 开始初始化请求体编码格式部分:
            document.getElementById('mytbody').innerHTML='<tr><td></td><td></td></tr>';
            document.getElementById('mytbody2').innerHTML='<tr><td></td><td></td></tr>';
            document.getElementById('mythead').innerHTML='  <tr>\n' +
            '                        <td style="width: 30%">Key</td>\n' +
            '                        <td style="width: 50%">Value</td>\n' +
            '                      </tr>';
             document.getElementById('mythead2').innerHTML='  <tr>\n' +
            '                        <td style="width: 30%">Key</td>\n' +
            '                        <td style="width: 50%">Value</td>\n' +
            '                      </tr>';
            document.getElementById('raw_Text').value = '';
            document.getElementById('raw_JavaScript').value = '';
            document.getElementById('raw_Json').value = '';
            document.getElementById('raw_Html').value = '';
            document.getElementById('raw_Xml').value = '';
            // 运行第三方表格插件的函数:
             $('#mytable').SetEditable({
                    $addButton: $('#add'),
                });
              $('#mytable2').SetEditable({
                    $addButton: $('#add2'),
                });
            if($("#apis").val() != 'none'){ // 判断不是第一个请选择,那就去获取接口信息
                $.get("/step_get_api/",{
                    "api_id":$("#apis").val()
                },function (ret) {
                    //拿到数据开始填充
                    console.log(ret)
                        var ret = eval(ret);
                        console.log(ret);
                        document.getElementById('step_method').value = ret.api_method;
                        document.getElementById('step_url').value = ret.api_url;
                        document.getElementById('step_host').value = ret.api_host;
                        document.getElementById('step_header').value = ret.api_header;
                        // 请求体编码格式
                        var body_method = '#'+ret.body_method;
                        $("li a[href="+body_method+"]").click();
                        // 请求体显示
                        if(ret.body_method == 'Text'){
                            document.getElementById('raw_Text').value = ret.api_body;
                        }
                        if(ret.body_method == 'JavaScript'){
                            document.getElementById('raw_JavaScript').value = ret.api_body;
                        }
                        if(ret.body_method == 'Json'){
                            document.getElementById('raw_Json').value = ret.api_body;
                        }
                        if(ret.body_method == 'Html'){
                            document.getElementById('raw_Html').value = ret.api_body;
                        }
                        if(ret.body_method == 'Xml'){
                            document.getElementById('raw_Xml').value = ret.api_body;
                        }
                        if(ret.body_method == 'form-data'){
                            var tbody = document.getElementById('mytbody'); // 定位表格中的tbody部分
                            body = eval(ret.api_body); //把这个像列表的字符串请求体变成真正的列表
                            for(var i=0;i<body.length;i++){ // 遍历这个请求体列表
                                key = body[i][0]; //拿出每一个键值对的key
                                value = body[i][1];//拿出每一个键值对的value
                                var childs_tr = tbody.children ;//获取到这个表格下面所有的tr组成的大列表
                                // 每个tr下的children得到的是 td列表,只有俩个。
                                childs_tr[i].children[0].innerText = key; //第一个td放key
                                childs_tr[i].children[1].innerText = value;//第二个td放value
                                //判断是否是最后一次遍历,来决定是否点击新增参数按钮
                                if(i<body.length-1){
                                    document.getElementById('add').click()
                                }
                            }
                        }
                        if(ret.body_method == 'x-www-form-urlencoded'){
                            var tbody = document.getElementById('mytbody2'); // 定位表格中的tbody部分
                            body = eval(ret.api_body); //把这个像列表的字符串请求体变成真正的列表
                            for(var i=0;i<body.length;i++){ // 遍历这个请求体列表
                                key = body[i][0]; //拿出每一个键值对的key
                                value = body[i][1];//拿出每一个键值对的value
                                var childs_tr = tbody.children ;//获取到这个表格下面所有的tr组成的大列表
                                // 每个tr下的children得到的是 td列表,只有俩个。
                                childs_tr[i].children[0].innerText = key; //第一个td放key
                                childs_tr[i].children[1].innerText = value;//第二个td放value
                                //判断是否是最后一次遍历,来决定是否点击新增参数按钮
                                if(i<body.length-1){
                                    document.getElementById('add2').click()
                            }
                        }
                    }
                })
            }
        });
    });
</script>

好,让我们刷新页面测试一下:

  1. 首先我在接口库创建了一个接口,数据如下:

图片

    2.我再去用例库的一个大用例下创建了一个小步骤,新的小步骤如下:

图片

    3.我现在要套用接口库接口了:

图片

    可以看到,所有地方全都准确的显示上了。

然后我们点击保存发现可以保存成功。

但是等我们再次打开的时候发现了bug:

图片

这个bug引起的原因应该是 加载的太慢导致,具体是我们初始化函数中,点击了一下none子标签,导致要显示这个不会携带 的文案刚准备显示出来的时候,系统瞬间切换到了form-data,所以这个文案还是偷偷的显示出来,没有被阻止。所以我们干脆不要点击none子标签了,多此一举了之前。:

图片

再次打开的时候就发现没有了:

图片

然后我们继续测试-多个接口来回套用,会有什么问题?

我们在接口库中再创建一个接口:

图片

然后去 步骤详情页来回切换 这俩个接口:

切换到接口1的时候 ,一切正常。

图片

然后切换到接口2的时候,bug出现。。图片图片图片

图片

平白无故 多了三个空行出来。这恶心的第三方插件,果然不可靠,这里也给大家长了点经验,能自己写的,千万不要随便用网上的第三方的,因为真的我们很难去改正bug。

不过我这里暂时不换了,毕竟都已经深入的写了这么多的代码了,而且bug也解决的很多了,估计也就剩这最后一个了。全都是前端的js。大家如果对这觉得不想好好细抠的话,直接复制代码 和源码覆盖即可,没必要浪费大量精力在这学习解决第三方的控件bug。

我们在控制显示多少行的时候,貌似使用了自动点击新参数按钮,然后具体点击几次,有个计数。代码在这里:

图片

也就是说,我们初始化了行数之后,根据真实数据一共有多少对,就点击多少次来做的。

看起来一点问题都没有,但是出现这么多空行,我觉得可能是点击一次,它新增了好多行。

经过实验,发现的确如此。

图片

我只点击了一下,居然多出四五行~ 。看来我们除了要初始化 thead / tbody之外,也要初始化下这个新增参数按钮 才行。

    但是考虑到 它的背后是第三方复杂的js函数,所以我们得去研究它背后的js函数:addBytton。

图片

我们按住command 查看这个方法的调用关系:

图片

我们点击一个进入到它原始js代码中:

图片

发现进入了一个模式的庞大复杂的js文件中,以作者的功底,看起来也是比较吃力~

但是怎么调试呢?我们这里加一个console.log。看看点击一次按钮,调用了几次吧:

图片

之后发现好的时候也就是一开始进入步骤详情页时候,点击是只执行一次:

图片

然后我们切换不同的接口,出现bug时候再点击一次:

图片

发现就很可怕了,居然每点击一次,就执行了三次这个函数!

 

所以我们只要想办法控制好,让他每点击一次就执行一遍即可,但是说起容易做起难。小伙伴们有其他方法的可以贡献一下这里的修改办法。

由于时间关系,这个bug的修改方法,下节课再分享哈~

欢迎持续关注哦~