基于HttpRunner,解析swagger数据,快速生成接口测试框架

使用HttpRunner默认生成的项目是这样的

  命令:httprunner --startproject  项目名称

so,根据这个项目的目录结构,使用python解析swagger接口参数,可以快速生成api、testcases、testsuites文件夹中用到的json文件

运行后的目录是这样的

  api目录

    按swagger中的tags区分为多个文件夹,每个文件夹下包含各自的api文件

  

  testcases目录

    按swagger中的tags区分为不同的json文件,每个文件包含所有的api接口

  

  testsuites目录

    测试用例集,组织运行所有的测试用例

  

 这样,接口测试框架的简易架子就有了。接下来,需要补充api接口文件数据

 

 略

 

运行结果

  

 HttpRunner自带的report

  

附lib目录下的代码

  swagger.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/9/9 15:17
# @Author  : lixiaofeng
# @Site    :
# @File    : swagger.py
# @Software: PyCharm

import os, requests
from httprunner import logger
from lib.processingJson import write_data, get_json

class AnalysisJson:
    """swagger自动生成测试用例"""

    def __init__(self, url):
        self.url = url
        self.interface = {}
        self.case_list = []
        self.tags_list = []
        self.http_suite = {"config": {"name": "", "base_url": "", "variables": {}},
                           "testcases": []}
        self.http_testcase = {"name": "", "testcase": "", "variables": {}}

    def retrieve_data(self):
        """
        主函数
        :return:
        """
        try:
            r = requests.get(self.url + ‘/v2/api-docs?group=sign-api‘).json()
            write_data(r, ‘data.json‘)
            # r = get_json(‘D:\HttpRunner_framework\\testcases\data.json‘)
        except Exception as e:
            logger.log_error(‘请求swagger url 发生错误. 详情原因: {}‘.format(e))
            return ‘error‘
        self.data = r[‘paths‘]  # 接口数据
        self.url = ‘https://‘ + r[‘host‘]
        self.title = r[‘info‘][‘title‘]
        self.http_suite[‘config‘][‘name‘] = self.title
        self.http_suite[‘config‘][‘base_url‘] = self.url

        self.definitions = r[‘definitions‘]  # body参数
        for tag_dict in r[‘tags‘]:
            self.tags_list.append(tag_dict[‘name‘])
        i = 0
        for tag in self.tags_list:
            self.http_suite[‘testcases‘].append({"name": "", "testcase": "", "variables": {}})
            self.http_suite[‘testcases‘][i][‘name‘] = tag
            self.http_suite[‘testcases‘][i][‘testcase‘] = ‘testcases/‘ + tag + ‘.json‘
            i += 1

        suite_path = os.path.join(os.path.abspath(os.path.join(os.path.dirname("__file__"), os.path.pardir)),
                                  ‘testsuites‘)
        testcase_path = os.path.join(suite_path, ‘demo_testsuite.json‘)
        write_data(self.http_suite, testcase_path)
        if isinstance(self.data, dict):
            for tag in self.tags_list:
                self.http_case = {"config": {"name": "", "base_url": "", "variables": {}}, "teststeps": []}

                for key, value in self.data.items():
                    for method in list(value.keys()):
                        params = value[method]
                        if not params[‘deprecated‘]:  # 接口是否被弃用
                            if params[‘tags‘][0] == tag:
                                self.http_case[‘config‘][‘name‘] = params[‘tags‘][0]
                                self.http_case[‘config‘][‘base_url‘] = self.url
                                case = self.retrieve_params(params, key, method, tag)
                                self.http_case[‘teststeps‘].append(case)
                        else:
                            logger.log_info(
                                ‘interface path: {}, if name: {}, is deprecated.‘.format(key, params[‘description‘]))
                            break
                api_path = os.path.join(os.path.abspath(os.path.join(os.path.dirname("__file__"), os.path.pardir)),
                                        ‘testcases‘)
                testcase_path = os.path.join(api_path, tag + ‘.json‘)
                write_data(self.http_case, testcase_path)

        else:
            logger.log_error(‘解析接口数据异常!url 返回值 paths 中不是字典.‘)
            return ‘error‘

    def retrieve_params(self, params, api, method, tag):
        """
        解析json,把每个接口数据都加入到一个字典中
        :param params:
        :param params_key:
        :param method:
        :param key:
        :return:
        replace(‘false‘, ‘False‘).replace(‘true‘, ‘True‘).replace(‘null‘,‘None‘)
        """
        http_interface = {"name": "", "variables": {},
                          "request": {"url": "", "method": "", "headers": {}, "json": {}, "params": {}}, "validate": [],
                          "output": []}
        http_testcase = {"name": "", "api": "", "variables": {}, "validate": [], "extract": [], "output": []}

        name = params[‘summary‘].replace(‘/‘, ‘_‘)
        http_interface[‘name‘] = name
        http_testcase[‘name‘] = name
        http_testcase[‘api‘] = ‘api/{}/{}.json‘.format(tag, name)
        http_interface[‘request‘][‘method‘] = method.upper()
        http_interface[‘request‘][‘url‘] = api.replace(‘{‘, ‘$‘).replace(‘}‘, ‘‘)
        parameters = params.get(‘parameters‘)  # 未解析的参数字典
        responses = params.get(‘responses‘)
        if not parameters:  # 确保参数字典存在
            parameters = {}
        for each in parameters:
            if each.get(‘in‘) == ‘body‘:  # body 和 query 不会同时出现
                schema = each.get(‘schema‘)
                if schema:
                    ref = schema.get(‘$ref‘)
                    if ref:
                        param_key = ref.split(‘/‘)[-1]
                        param = self.definitions[param_key][‘properties‘]
                        for key, value in param.items():
                            if ‘example‘ in value.keys():
                                http_interface[‘request‘][‘json‘].update({key: value[‘example‘]})
                            else:
                                http_interface[‘request‘][‘json‘].update({key: ‘‘})
            elif each.get(‘in‘) == ‘query‘:
                name = each.get(‘name‘)
                for key in each.keys():
                    if ‘example‘ in key:
                        http_interface[‘request‘][‘params‘].update({name: each[key]})
        for each in parameters:
            # if each.get(‘in‘) == ‘path‘:
            #     name = each.get(‘name‘)
            #     for key in each.keys():
            #         if ‘example‘ in key:
            #             http_interface[‘request‘][‘json‘].update({name: each[key]})
            #     else:
            #
            #         http_interface[‘request‘][‘json‘].update({name: ‘‘})
            if each.get(‘in‘) == ‘header‘:
                name = each.get(‘name‘)
                for key in each.keys():
                    if ‘example‘ in key:
                        http_interface[‘request‘][‘headers‘].update({name: each[key]})
                    else:
                        if name == ‘token‘:
                            http_interface[‘request‘][‘headers‘].update({name: ‘$token‘})
                        else:
                            http_interface[‘request‘][‘headers‘].update({name: ‘‘})
        for key, value in responses.items():
            schema = value.get(‘schema‘)
            if schema:
                ref = schema.get(‘$ref‘)
                if ref:
                    param_key = ref.split(‘/‘)[-1]
                    res = self.definitions[param_key][‘properties‘]
                    i = 0
                    for k, v in res.items():
                        if ‘example‘ in v.keys():
                            http_interface[‘validate‘].append({"eq": []})
                            http_interface[‘validate‘][i][‘eq‘].append(‘content.‘ + k)
                            http_interface[‘validate‘][i][‘eq‘].append(v[‘example‘])

                            http_testcase[‘validate‘].append({"eq": []})
                            http_testcase[‘validate‘][i][‘eq‘].append(‘content.‘ + k)
                            http_testcase[‘validate‘][i][‘eq‘].append(v[‘example‘])
                            i += 1
                else:
                    http_interface[‘validate‘].append({"eq": []})
            else:
                http_interface[‘validate‘].append({"eq": []})
        if http_interface[‘request‘][‘json‘] == {}:
            del http_interface[‘request‘][‘json‘]
        if http_interface[‘request‘][‘params‘] == {}:
            del http_interface[‘request‘][‘params‘]

        api_path = os.path.join(os.path.abspath(os.path.join(os.path.dirname("__file__"), os.path.pardir)), ‘api‘)
        tags_path = os.path.join(api_path, tag)
        if not os.path.exists(tags_path):
            os.mkdir(tags_path)
        json_path = os.path.join(tags_path, http_interface[‘name‘] + ‘.json‘)
        write_data(http_interface, json_path)

        return http_testcase

if __name__ == ‘__main__‘:
    AnalysisJson(‘1‘).retrieve_data()

简单的实现了功能,代码有些粗糙~~~

  processingJson.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/9/9 15:18
# @Author  : lixiaofeng
# @Site    :
# @File    : processingJson.py
# @Software: PyCharm

import json
from httprunner import logger

def get_json(path, field=‘‘):
    """
    获取json文件中的值,data.json和res.json可共用
    :param path:
    :param field:
    :return:
    """
    with open(path, ‘r‘, encoding=‘utf-8‘) as f:
        json_data = json.load(f)
        if field:
            data = json_data.get(field)
            return data
        else:
            return json_data

def write_data(res, json_path):
    """
    把处理后的参数写入json文件
    :param res:
    :param json_path:
    :return:
    """
    if isinstance(res, dict) or isinstance(res, list):
        with open(json_path, ‘w‘, encoding=‘utf-8‘) as f:
            json.dump(res, f, ensure_ascii=False, sort_keys=True, indent=4)
            logger.log_info(‘Interface Params Total:{} ,write to json file successfully!\n‘.format(len(res)))
    else:
        logger.log_error(‘{} Params is not dict.\n‘.format(write_data.__name__))

具体业务场景的测试,可以按照导入.har文件的方法快速生成,总之还是挺便捷的。

之前就有关注HttpRunner,终于有空花了一天时间,大致过了一遍中文文档,简单的记录下学习成果~~~

原文地址:https://www.cnblogs.com/changqing8023/p/11515731.html

时间: 2024-10-15 00:21:12

基于HttpRunner,解析swagger数据,快速生成接口测试框架的相关文章

Android 网络请求json数据,解析json数据,生成对应的java bean类一步到位,快速开发

Android 网络请求一般都涉及到图片和JSON数据,怎样快速的请求网络JSON数据,解析JSON数据,并且一步生成自己想要的Java bean实体类?这个涉及到Android 开发效率的问题.由于接触Android 网络这方面比较多,自然就找到一些好的方法来快速开发Android 网络模块的相关内容,接下来就为大家揭晓 一步快速请求,解析JSON 数据生成对应的Java bean实体类的方法. 注:我们先把思路讲解下吧: 1.网络请求JSON数据代码可以自己写,当然我还是推荐使用网络上开源的

快速生成R语言实现Genetic Linkage Model参数估计方法的报告

第一篇随笔,打算把搞过的东西整理一下-test- 基于Rstudio与Markdown可以快速生成R语言报告,结果可直接发布在RPubs,当然,你应当注册一个RPubs账号. 先来一发已发布的报告[Genetic Linkage Model],主要介绍了利用Newton-Raphson.EM.Gibbs这三种经典算法对Genetic Linkage Model做参数估计的方法和R代码.

修改设置Sublime Text3 Emmet插件生成html框架中默认lang="en"为lang="zh-cn"

这里用的是sublime text3汉化版,sublime text3汉化教程 和 sublime text3 安装emmet插件教程 sublime text3安装emmet插件后,默认快捷生成html框架中的语言设置是lang="en" 进入emmet设置中的Settings-User 复制下面的代码进去然后保存即可 { "snippets": { "variables": { "lang": "zh-cn&qu

iOS开发之JSON格式数据的生成与解析

本文将从四个方面对IOS开发中JSON格式数据的生成与解析进行讲解: 一.JSON是什么? 二.我们为什么要用JSON格式的数据? 三.如何生成JSON格式的数据? 四.如何解析JSON格式的数据?  JSON格式取代了xml给网络传输带来了很大的便利,但是却没有了xml的一目了然,尤其是json数据很长的时候,我们会陷入繁琐复杂的数据节点查找中.这时我们就需要一款在线校验工具 BeJson. 一.JSON是什么? JSON(JavaScript Object Notation) 是一种轻量级的

JSON数据的生成与解析

JSON数据的生成与解析,首先先到网上下载一个json jar包,我用的是org.json 示例代码: package json; import org.json.JSONArray; import org.json.JSONObject; public class Main { /** * 生成Json数据 */ public static String createJson(){ JSONObject json = new JSONObject(); json.put("classId&qu

fastjson生成和解析json数据,序列化和反序列化数据

本文讲解2点: 1. fastjson生成和解析json数据 (举例:4种常用类型:JavaBean,List<JavaBean>,List<String>,List<Map<String,Object>) 2.通过一个android程序测试fastjson的用法. fastjson简介: Fastjson是一个Java语言编写的高性能功能完善的JSON库.fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jack

[Oracle]快速生成大量模拟数据的方法

快速生成大量模拟数据的方法: create table TEST(id integer, TEST_NUMBER NUMBER(18,6)); insert into TEST select i+j, i+j   from  (          with DATA2(j) as (                            select 0 j from DUAL                              union all                     

快速基于echarts的大数据可视化

[Author]: kwu 快速基于echarts的大数据可视化,echarts纯粹的js实现的图表工具,快速开发的步骤如下: 1.引入echarts的依赖js库 <script type="text/javascript" src="js/esl/esl.js"></script> <script type="text/javascript" src="js/echarts.js"><

C#快速生成数据数组

需求:生成一个数组,数组里面的值为1-100实现方式:拿到这个需求很多朋友可能会想到一个快速实现的方式如下: int[] arr=new int[100]; for(int i=1;i<=100;i++){ arr[i]=i; } 但是C#提供了一个快速生成的方式如下: int[] arr = Enumerable.Range(1, 100).ToArray(); 这样看起来代码就简洁多了