接口测试平台188: 并发报告(4)

2022-05-20 09:31:35 浏览数 (1)

好的,本节课我们要解决的就是 上节课我们拼好的json中的 各层级的result结果:

先来看我们当前的数据:

代码语言:javascript复制
{'result': '',
 'cases': [
       {'case_id': 21, 
       'case_name': '大用例1', 
       'result_case': '', 
       'steps': [
               {'step_id': 67, 
               'step_name': '调用A接口步骤', 
               'result_step': '', 
               'data': {
                     'request_data': '{"url": "http://127.0.0.1:8000/test_api_A", "method": "get", "api_body": "", "api_body_method": "none"}', 
                     'response': '{"errcode": "0"}', 
                     'assert_result': '{}'
                     }
                  }
                ]
       },
       {'case_id': 22,
        'case_name': '大用例2',
         'result_case': '', 
         'steps': [
                {'step_id': 68, 
                'step_name': '测试B接口步骤1', 
                'result_step': '', 
                'data': {
                    'request_data': '{"url": "http://127.0.0.1:8000/test_api_B", "method": "get", "api_body": "", "api_body_method": "none"}',
                     'response': '{"errcode": "0"}',
                      'assert_result': '{}'
                      }
                  }, 
                 {'step_id': 69, 
                 'step_name': '测试B接口步骤2',
                  'result_step': '', 
                  'data': {
                       'request_data': '{"url": "http://127.0.0.1:8000/test_api_B", "method": "get", "api_body": "", "api_body_method": "none"}', 
                       'response': '{"errcode": "0"}',
                        'assert_result': '{}'
                        }
                    }
                ]
            }
         ]
    }

我们先来思考下:

最外层的resutl 是由谁决定的?当然是内层的result_case ,

而result_case又是由谁决定的呢?当然是自己内层的result_step,

那么result_step 又是由谁决定的呢?当然是内部的assert_result。

所以我们的开发思路,必然是从内向外逐步进展。

那就要先考虑这个最内部的assert_result。

我们先回顾下 这个断言结果,我们存入数据库的时候代码是怎么写的?

上面代码可以看出,每个step的断言,都是一个字典,key为这个断言的设置文本本身。值为 真 / 假 (True/False)

而我们的最终结果,无论哪一级,都不会关心key,只会关心value是否存在False

所以我们的result_step 要怎么确定?

当然是遍历这个assert_result ,只要保证它内部没有False值,那么result_step就是True !

但是这个assert_result又是什么呢?原来它是tmp_assert_result的 json 字符串...

所以我们要遍历它的话,就只能先给它恢复成字典。

所以代码如下:

上图中,我们遍历了这个字典,判断内部是否有False , 只要发现一个False,我们就会给tmp_step["result_step"] 立即变成False, 并且终止循环,因为已经无需再测了。

如果一直到循环结束,都没有发现False, 那么就可以给tmp_step["result_step"]光荣的写成True了。

然后我们继续思考下一个问题。

如果这个s_report.assert_result 为空呢?也就是说这个接口步骤压根没有任何断言。

那么我们应该理所应当的,给tmp_step["result_step"] 写成True了。所以要在这个for 外面裹上一层判断if:

注意,这个if, 我并没有简单的写成 == ‘’ ,而是写成了 in [None,'',' ']

这样的好处是可以增加很大的容错性,因为我也害怕数据库因为某些意外存的并不是空字符串,而是None空型或者 其他纯空格什么的... 以后如果发现其他异常的参数,都可以写到这个列表中,更方便。

好,到这里我们搞定了这个step层级的result,然后继续往外搞result_case:

这里我们要思考下在哪里写这个判断代码,按理说应该是循环steps,判断其中的result_step是否有false, 来判断result_case的结果。

但是这样做显然需要额外一个for循环,会严重拖慢速度,那么有什么简单的方式呢

当然有,而且很多。

比如,我们给result_case 一开始就默认设置成True ,然后如果发现result_step有False,则给result_case 再改成False不迟。 这样代码量会大大减少,而且没有额外增加循环:

其实这个道理 可以应用在任何层级上。就连我们刚刚写的result_step的值 也可以先变成True,然后查到一个assert_result[i] 为False 再改不迟。但是既然已经写完了,就算了。

我们继续往外写,最外层的结果:

代码语言:javascript复制
res["result"]

这个的道理我们同样,可以给先变成True, :

改成这样后,我们就可以测试了:之前的大用例,虽然有俩个,但是很明显,我们没有给任何step加断言,所以结果一定是成功的。显示如下:

代码语言:javascript复制
{'result': True, 
 'cases': [{'case_id': 21, 'case_name': '大用例1', 
            'result_case': True, 
            'steps': [{'step_id': 67, 'step_name': '调用A接口步骤',
             'result_step': True, 
             'data': {'request_data': '{"url": "http://127.0.0.1:8000/test_api_A", "method": "get", "api_body": "", "api_body_method": "none"}', 'response': '{"errcode": "0"}', 'assert_result': '{}'}}]}, 
           {'case_id': 22, 'case_name': '大用例2',
            'result_case': True, 
            'steps': [{'step_id': 68, 'step_name': '测试B接口步骤1',
             'result_step': True, 
             'data': {'request_data': '{"url": "http://127.0.0.1:8000/test_api_B", "method": "get", "api_body": "", "api_body_method": "none"}', 'response': '{"errcode": "0"}', 'assert_result': '{}'}},
              {'step_id': 69, 'step_name': '测试B接口步骤2',
               'result_step': True, 
               'data': {'request_data': '{"url": "http://127.0.0.1:8000/test_api_B", "method": "get", "api_body": "", "api_body_method": "none"}', 'response': '{"errcode": "0"}', 'assert_result': '{}'}}]}]}

看到了吧。不过我们现在要在第二个大用例的第二个步骤的断言中 手动写个False, 来测试一下:

测试结果 出现错误!!!

我们来看这段代码:

大家发现我挖的坑了么?

s_report.assert_result 只是个字符串json, 没法用[i]的方式拿到里面的值,而我们前面for中的 是用了json.loads() ,所以这里我们需要改成:

这样大家印象深刻了么?json只不过是个字符串哦~

那报错到底说的什么意思呢?说的是:

“字符串的下标必须是整形!”

原来系统把我们[i] 当成是求下标了,其实我们是求字典的值哦,所以i 并不是整形而是某个字符串....

好了明白之后修复好我们再次测试:

这次就有了结果了,方便大家查看,我再次加几个回车展示给大家:

代码语言:javascript复制
{'result': False, 
'cases': [
     {'case_id': 21, 'case_name': '大用例1', 
     'result_case': True, 
     'steps': [{'step_id': 67, 'step_name': '调用A接口步骤',
            'result_step': True, 'data': {'request_data': '{"url": "http://127.0.0.1:8000/test_api_A", "method": "get", "api_body": "", "api_body_method": "none"}', 'response': '{"errcode": "0"}', 'assert_result': '{}'}}]},
     {'case_id': 22, 'case_name': '大用例2', 
     'result_case': False, 
     'steps': [{'step_id': 68, 'step_name': '测试B接口步骤1',
               'result_step': True, 'data': {'request_data': '{"url": "http://127.0.0.1:8000/test_api_B", "method": "get", "api_body": "", "api_body_method": "none"}', 'response': '{"errcode": "0"}', 'assert_result': '{}'}},
                {'step_id': 69, 'step_name': '测试B接口步骤2', 
                'result_step': False, 'data': {'request_data': '{"url": "http://127.0.0.1:8000/test_api_B", "method": "get", "api_body": "", "api_body_method": "none"}', 'response': '{"errcode": "0"}', 'assert_result': '{"aaa":false}'}}]}]}

我们的预期,就是第二个用例的第二个步骤 出错,导致第二个用例也是错的,导致最终结果是错的。

但是第一个用例和内部的step都是无辜的,所以仍然保持True 。

好了,结果完美成功,本节课到此结束,欢迎关注下节课。

下节课我们就要开始写个前端报告页面了。来使用这套数据展示。

0 人点赞