zoukankan      html  css  js  c++  java
  • 基于HttpRunner,解析swagger数据,快速生成接口测试框架-优化篇

    之前写过一个 基于HttpRunner,解析swagger数据,快速生成接口测试框架,今天抽时间又优化了下

    使用最新的httprunner 2.3.2 版本。默认好像没有生成测试报告,需要简单的修改下源码:

    # api.py 217行 添加
    report_path = report.gen_html_report(self._summary)
    
    # 修改报告的默认命名方式
    # report.py 301行-310行
    start_at_timestamp = int(summary["time"]["start_at"])
    summary["time"]["start_datetime"] = datetime.fromtimestamp(start_at_timestamp).strftime('%Y-%m-%d %H:%M:%S')
    time_format= datetime.fromtimestamp(start_at_timestamp).strftime('%Y-%m-%d %H-%M-%S')
    
    if report_file:
        report_dir = os.path.dirname(report_file)
        report_file_name = os.path.basename(report_file)
    else:
        report_dir = report_dir or os.path.join(os.getcwd(), "reports")
        report_file_name = "{}.html".format(time_format)
    
    # log,修改api.py 33-36行,默认输出日志文件到框架目录下的logs中
    log_path = os.path.join(os.getcwd(), "logs")
    if not os.path.exists(log_path): os.mkdir(log_path)
    time_format = datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d')
    if not os.path.exists(log_file): log_file = os.path.join(log_path, log_file + time_format + ".log")
    
    logger.setup_logger(log_level, log_file)

    修改了 processingJson.py ,在从swagger拉取接口时,判断,保留已修改的json文件内容<在已运行的json接口文件中加参数 noReset >

    import json, os
    # from httprunner import logger
    from common.logger 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! {}
    '.format(len(res), json_path))
        else:
            logger.log_error('{} Params is not dict.
    '.format(write_data.__name__))
    
    
    def check_json(res: dict or list, json_path: str, field: str = "noReset"):
        """
        接口路口已存在的,不重置,只添加删除参数,设置 noReset 参数为 true;
        :param res:
        :param json_path:
        :param field:
        :return:
        """
        if os.path.exists(json_path):
            noReset = get_json(json_path, field)
            if noReset:
                data = get_json(json_path)
                res[field] = True
                not_reset_json(data, res)
                if "teststeps" in res.keys():
                    for teststep in res.get("teststeps", []):
                        teststep["validate"] = []
                elif "testcases" in res.keys():
                    res["testcases"] = data.get("testcases", [])
        else:
            with open("接口更新记录.txt", "a") as f:
                f.write("新增 api :{}".format(json_path))
        write_data(res, json_path)
    
    
    def not_reset_json(data, res):
        """
        递归,data 中已存在值,则替换到 res 中
        :param data:
        :param res:
        :return:
        """
        if isinstance(data, dict):
            for key, value in data.items():
                if isinstance(value, (dict, list)):
                    not_reset_json(value, res[key])
                elif isinstance(value, str):
                    res[key] = value
        elif isinstance(data, list):
            for i in range(len(data)):
                if isinstance(data[i], (dict, list)):
                    try:
                        not_reset_json(data[i], res[i])
                    except IndexError:
                        try:
                            res.update(data[i])
                        except AttributeError:
                            res.append(data[i])
                else:
                    res[i] = data[i]
        elif isinstance(data, str):
            logger.log_info("外层判断,data是str :{}".format(data))
    
    
    def comparison_document():
        """
        比较suite/testceae和api文件的差异,发现未运行的接口
        :return:
        """
        from common.logger import BASE_DIR
        if os.path.exists("comparison_document.txt"):
            os.remove("comparison_document.txt")
        api_path = os.path.join(BASE_DIR, "api")
        suite_path = os.path.join(BASE_DIR, "testsuitesdemo_testsuite.json")
        api_file_list = os.listdir(api_path)
        suite_data = get_json(suite_path)
        suite_list = suite_data.get("testcases", [])
        suite_api_list = []
        for api in suite_list:
            suite_api_list.append(api["name"])
        with open("comparison_document.txt", "a", encoding="utf-8") as f:
            f.write("--------------testsuite未设置接口--------------------------" + "
    ")
        for api_name in api_file_list:
            if api_name not in suite_api_list:
                with open("comparison_document.txt", "a", encoding="utf-8") as f:
                    f.write(os.path.join(api_path, api_name) + "
    ")
    
        testcase_path = os.path.join(BASE_DIR, "testcases")
        testcase_file_list = os.listdir(testcase_path)
    
        with open("comparison_document.txt", "a", encoding="utf-8") as f:
            f.write("--------------testcase未设置接口--------------------------" + "
    ")
        for file in testcase_file_list:
            testcase_file_path = os.path.join(testcase_path, file)
            testcase_data = get_json(testcase_file_path)
            title = testcase_data.get("config", {}).get("name", "")
            teststeps_list = testcase_data.get("teststeps", {})
            testcase_api_list = []
            for api in teststeps_list:
                if title in api.get("api", ""):
                    testcase_api_list.append(api.get("name", "") + ".json")
            for api_name in api_file_list:
                if api_name == title:
                    api_name_list = os.listdir(os.path.join(api_path, api_name))
                    for api in api_name_list:
                        if api not in testcase_api_list:
                            with open("comparison_document.txt", "a", encoding="utf-8") as f:
                                f.write(os.path.join(os.path.join(api_path, api_name), api) + "
    ")
    
    
    if __name__ == '__main__':
        comparison_document()

    有新增的接口时,会输出 接口更新记录.txt 文件

    comparison_document() 方法,可以避免有遗漏的没有运行的 api

    swagger.py 写入json文件的方法,需要更换成 check_json()

    so,先这样~~~

  • 相关阅读:
    Nokia Qt SDK开发环境使用
    iPad不久将能使用Android系统
    原生IDE新军:JRuby阵营的RedCar,JavaScript阵营的Cloud9(自己写个IDE出来一定很复杂吧)
    手机产品的信息架构
    百万开发者拥戴!七大.NET著名开源项目
    Prism 4.0发布最终版,支持Windows Phone 7
    Qt Symbian 开发环境安装
    Qt 4.7.1 和 Mobility 1.1.0 已发布
    WSI闭关,这对WS*意味着什么?(个人觉得Web Services是个好东西)
    ERROR: unknown virtual device name解决方法
  • 原文地址:https://www.cnblogs.com/changqing8023/p/12163691.html
Copyright © 2011-2022 走看看