Ejemplo n.º 1
0
def dump_json_file(json_data, pwd_dir_path, dump_file_name):
    """ dump json data to file
    """
    logs_dir_path = os.path.join(pwd_dir_path, "logs")
    if not os.path.isdir(logs_dir_path):
        os.makedirs(logs_dir_path)

    dump_file_path = os.path.join(logs_dir_path, dump_file_name)

    try:
        with io.open(dump_file_path, 'w', encoding='utf-8') as outfile:
            if is_py2:
                outfile.write(
                    unicode(json.dumps(
                        json_data,
                        indent=4,
                        separators=(',', ':'),
                        ensure_ascii=False
                    ))
                )
            else:
                json.dump(
                    json_data,
                    outfile,
                    indent=4,
                    separators=(',', ':'),
                    ensure_ascii=False
                )

        msg = "dump file: {}".format(dump_file_path)
        logger.color_print(msg, "BLUE")

    except TypeError:
        msg = "Failed to dump json file: {}".format(dump_file_path)
        logger.color_print(msg, "RED")
Ejemplo n.º 2
0
def create_scaffold(project_path):
    if os.path.isdir(project_path):
        folder_name = os.path.basename(project_path)
        logger.log_warning(u"Folder {} exists, please specify a new folder name.".format(folder_name))
        return

    logger.color_print("Start to create new project: {}\n".format(project_path), "GREEN")

    def create_path(path, ptype):
        if ptype == "folder":
            os.makedirs(path)
        elif ptype == "file":
            open(path, 'w').close()

        return "created {}: {}\n".format(ptype, path)

    path_list = [
        (project_path, "folder"),
        (os.path.join(project_path, "tests"), "folder"),
        (os.path.join(project_path, "tests", "api"), "folder"),
        (os.path.join(project_path, "tests", "suite"), "folder"),
        (os.path.join(project_path, "tests", "testcases"), "folder"),
        (os.path.join(project_path, "tests", "debugtalk.py"), "file")
    ]

    msg = ""
    for p in path_list:
        msg += create_path(p[0], p[1])

    logger.color_print(msg, "BLUE")
Ejemplo n.º 3
0
def prettify_json_file(file_list):
    """ prettify JSON testset format
    """
    for json_file in set(file_list):
        if not json_file.endswith(".json"):
            logger.log_warning("Only JSON file format can be prettified, skip: {}".format(json_file))
            continue

        logger.color_print("Start to prettify JSON file: {}".format(json_file), "GREEN")

        dir_path = os.path.dirname(json_file)
        file_name, file_suffix = os.path.splitext(os.path.basename(json_file))
        outfile = os.path.join(dir_path, "{}.pretty.json".format(file_name))

        with io.open(json_file, 'r', encoding='utf-8') as stream:
            try:
                obj = json.load(stream)
            except ValueError as e:
                raise SystemExit(e)

        with io.open(outfile, 'w', encoding='utf-8') as out:
            json.dump(obj, out, indent=4, separators=(',', ': '))
            out.write('\n')

        print("success: {}".format(outfile))
Ejemplo n.º 4
0
def dump_json_file(json_data, json_file_abs_path):
    """ dump json data to file
    """
    class PythonObjectEncoder(json.JSONEncoder):
        def default(self, obj):
            try:
                return super().default(self, obj)
            except TypeError:
                return str(obj)

    try:
        with io.open(json_file_abs_path, 'w', encoding='utf-8') as outfile:
            if is_py2:
                outfile.write(
                    unicode(
                        json.dumps(json_data,
                                   indent=4,
                                   separators=(',', ':'),
                                   ensure_ascii=False,
                                   cls=PythonObjectEncoder)))
            else:
                json.dump(json_data,
                          outfile,
                          indent=4,
                          separators=(',', ':'),
                          ensure_ascii=False,
                          cls=PythonObjectEncoder)

        msg = "dump file: {}".format(json_file_abs_path)
        logger.color_print(msg, "BLUE")

    except TypeError as ex:
        msg = "Failed to dump json file: {}\nReason: {}".format(
            json_file_abs_path, ex)
        logger.color_print(msg, "RED")
Ejemplo n.º 5
0
def main_hrun():
    """ API test: parse command line options and run commands.
    """
    parser = argparse.ArgumentParser(
        description='HTTP test runner, not just about api test and load test.')
    parser.add_argument('-V',
                        '--version',
                        dest='version',
                        action='store_true',
                        help="show version")
    parser.add_argument('testset_paths', nargs='*', help="testset file path")
    parser.add_argument(
        '--html-report-name',
        help=
        "specify html report name, only effective when generating html report."
    )
    parser.add_argument('--html-report-template',
                        help="specify html report template path.")
    parser.add_argument('--log-level',
                        default='INFO',
                        help="Specify logging level, default is INFO.")
    parser.add_argument(
        '--dot-env-path',
        help=
        "Specify .env file path, which is useful for keeping production credentials."
    )
    parser.add_argument(
        '--failfast',
        action='store_true',
        default=False,
        help="Stop the test run on the first error or failure.")
    parser.add_argument('--startproject', help="Specify new project name.")

    args = parser.parse_args()
    logger.setup_logger(args.log_level)

    if args.version:
        logger.color_print("{}".format(__version__), "GREEN")
        exit(0)

    dot_env_path = args.dot_env_path or os.path.join(os.getcwd(), ".env")
    if dot_env_path:
        load_dot_env_file(dot_env_path)

    project_name = args.startproject
    if project_name:
        project_path = os.path.join(os.getcwd(), project_name)
        create_scaffold(project_path)
        exit(0)

    result = HttpRunner(
        args.testset_paths,
        failfast=args.failfast).run(html_report_name=args.html_report_name)

    print_output(result["output"])
    return 0 if result["success"] else 1
Ejemplo n.º 6
0
Archivo: cli.py Proyecto: gzs4850/IFTC
def main_hrun():
    """ API test: parse command line options and run commands.
    """
    parser = argparse.ArgumentParser(
        description='HTTP test runner, not just about api test and load test.')
    parser.add_argument('-V',
                        '--version',
                        dest='version',
                        action='store_true',
                        help="show version")
    parser.add_argument('testset_paths', nargs='*', help="testset file path")
    parser.add_argument('--log-level',
                        default='INFO',
                        help="Specify logging level, default is INFO.")
    parser.add_argument(
        '--failfast',
        action='store_true',
        default=False,
        help="Stop the test run on the first error or failure.")
    parser.add_argument('--startproject', help="Specify new project name.")

    args = parser.parse_args()
    logger.setup_logger(args.log_level)

    args.testset_paths = 'E:\case'

    if args.version:
        logger.color_print("HttpRunner version: {}".format(hrun_version),
                           "GREEN")
        logger.color_print("PyUnitReport version: {}".format(pyu_version),
                           "GREEN")
        exit(0)

    project_name = args.startproject
    if project_name:
        project_path = os.path.join(os.getcwd(), project_name)
        create_scaffold(project_path)
        exit(0)

    kwargs = {
        "output": os.path.join(os.getcwd(), "reports"),
        "failfast": args.failfast
    }
    test_runner = HTMLTestRunner(**kwargs)
    result = run_suite_path(args.testset_paths, {}, test_runner)
    print_output(result.output)

    return 0 if result.success else 1
Ejemplo n.º 7
0
def validate_json_file(file_list):
    """ validate JSON testcase format
    """
    for json_file in set(file_list):
        if not json_file.endswith(".json"):
            logger.log_warning("Only JSON file format can be validated, skip: {}".format(json_file))
            continue

        logger.color_print("Start to validate JSON file: {}".format(json_file), "GREEN")

        with io.open(json_file) as stream:
            try:
                json.load(stream)
            except ValueError as e:
                raise SystemExit(e)

        print("OK")
Ejemplo n.º 8
0
def validate_json_file(file_list):
    """ validate JSON testset format
    """
    for json_file in set(file_list):
        if not json_file.endswith(".json"):
            logger.log_warning("Only JSON file format can be validated, skip: {}".format(json_file))
            continue

        logger.color_print("Start to validate JSON file: {}".format(json_file), "GREEN")

        with io.open(json_file) as stream:
            try:
                json.load(stream)
            except ValueError as e:
                raise SystemExit(e)

        print("OK")
Ejemplo n.º 9
0
def parse_locustfile(file_path):
    """ parse testcase file and return locustfile path.
        if file_path is a Python file, assume it is a locustfile
        if file_path is a YAML/JSON file, convert it to locustfile
    """
    if not os.path.isfile(file_path):
        color_print("file path invalid, exit.", "RED")
        sys.exit(1)

    file_suffix = os.path.splitext(file_path)[1]
    if file_suffix == ".py":
        locustfile_path = file_path
    elif file_suffix in ['.yaml', '.yml', '.json']:
        locustfile_path = gen_locustfile(file_path)
    else:
        # '' or other suffix
        color_print("file type should be YAML/JSON/Python, exit.", "RED")
        sys.exit(1)

    return locustfile_path
def parse_locustfile(file_path):
    """
    解析testcase文件并返回locustfile路径
    如果file_path是一个Python文件,则假设它是一个locustfile
    如果file_path是YAML/JSON文件,将其转换为locustfile
    :param file_path:
    :return:
    """
    if not os.path.isfile(file_path):
        logger.color_print("文件路径无效,退出.", "RED")
        sys.exit(1)

    file_suffix =os.path.splitext(file_path)[1]
    if file_suffix == ".py":
        locustfile_path = file_path
    elif file_suffix in [".yml", ".yaml", ".json"]:
        locustfile_path = gen_locustfile(file_path)
    else:
        logger.color_print("文件类型必须是yml,json,python,exit", "RED")
        sys.exit(1)

    return locustfile_path
Ejemplo n.º 11
0
def parse_locustfile(file_path):
    """ parse testcase file and return locustfile path.
        解析testcase文件并返回locustfile路径
        if file_path is a Python file, assume it is a locustfile
        如果file_path是一个Python文件,则假设它是一个locustfile
        if file_path is a YAML/JSON file, convert it to locustfile
        如果file_path是YAML/JSON文件,将其转换为locustfile
    """
    if not os.path.isfile(file_path):
        logger.color_print("file path invalid, exit.", "RED")
        sys.exit(1)

    file_suffix = os.path.splitext(file_path)[1]  # 文件后缀名
    if file_suffix == ".py":
        locustfile_path = file_path
    elif file_suffix in ['.yaml', '.yml', '.json']:
        locustfile_path = gen_locustfile(file_path)  #把用例文件转变成py文件
    else:
        # '' or other suffix
        logger.color_print("file type should be YAML/JSON/Python, exit.",
                           "RED")
        sys.exit(1)

    return locustfile_path
Ejemplo n.º 12
0
import sys

from httprunner.cli import main_hrun, main_locust
from httprunner.logger import color_print

cmd = sys.argv.pop(1)

if cmd in ["hrun", "httprunner", "ate"]:
    main_hrun()
elif cmd in ["locust", "locusts"]:
    main_locust()
else:
    color_print("Miss debugging type.", "RED")
    example = "\n".join([
        "e.g.",
        "python main-debug.py hrun /path/to/testset_file",
        "python main-debug.py locusts -f /path/to/testset_file"
    ])
    color_print(example, "yellow")
Ejemplo n.º 13
0
def main():
    """ API test: parse command line options and run commands.
    """
    if is_py2:
        color_print(get_python2_retire_msg(), "YELLOW")

    parser = argparse.ArgumentParser(description=__description__)
    parser.add_argument(
        '-V', '--version', dest='version', action='store_true',
        help="show version")
    parser.add_argument(
        'testfile_paths', nargs='*',
        help="Specify api/testcase/testsuite file paths to run.")
    parser.add_argument(
        '--log-level', default='INFO',
        help="Specify logging level, default is INFO.")
    parser.add_argument(
        '--log-file',
        help="Write logs to specified file path.")
    parser.add_argument(
        '--dot-env-path',
        help="Specify .env file path, which is useful for keeping sensitive data.")
    parser.add_argument(
        '--report-template',
        help="Specify report template path.")
    parser.add_argument(
        '--report-dir',
        help="Specify report save directory.")
    parser.add_argument(
        '--report-file',
        help="Specify report file path, this has higher priority than specifying report dir.")
    parser.add_argument(
        '--save-tests', action='store_true', default=False,
        help="Save loaded/parsed/summary json data to JSON files.")
    parser.add_argument(
        '--failfast', action='store_true', default=False,
        help="Stop the test run on the first error or failure.")
    parser.add_argument(
        '--startproject',
        help="Specify new project name.")
    parser.add_argument(
        '--validate', nargs='*',
        help="Validate JSON testcase format.")
    parser.add_argument(
        '--prettify', nargs='*',
        help="Prettify JSON testcase format.")

    args = parser.parse_args()

    if len(sys.argv) == 1:
        # no argument passed
        parser.print_help()
        sys.exit(0)

    if args.version:
        color_print("{}".format(__version__), "GREEN")
        sys.exit(0)

    if args.validate:
        validate_json_file(args.validate)
        sys.exit(0)
    if args.prettify:
        prettify_json_file(args.prettify)
        sys.exit(0)

    project_name = args.startproject
    if project_name:
        create_scaffold(project_name)
        sys.exit(0)

    runner = HttpRunner(
        failfast=args.failfast,
        save_tests=args.save_tests,
        log_level=args.log_level,
        log_file=args.log_file
    )

    err_code = 0
    try:
        for path in args.testfile_paths:
            summary = runner.run(path, dot_env_path=args.dot_env_path)
            report_dir = args.report_dir or os.path.join(runner.project_working_directory, "reports")
            gen_html_report(
                summary,
                report_template=args.report_template,
                report_dir=report_dir,
                report_file=args.report_file
            )
            err_code |= (0 if summary and summary["success"] else 1)
    except Exception as ex:
        color_print("!!!!!!!!!! exception stage: {} !!!!!!!!!!".format(runner.exception_stage), "YELLOW")
        color_print(str(ex), "RED")
        capture_exception(ex)
        err_code = 1

    sys.exit(err_code)
Ejemplo n.º 14
0
def main_hrun():
    """ API test: parse command line options and run commands.
    """
    parser = argparse.ArgumentParser(description=__description__)
    parser.add_argument(
        '-V', '--version', dest='version', action='store_true',
        help="show version")
    parser.add_argument(
        'testset_paths', nargs='*',
        help="testset file path")
    parser.add_argument(
        '--no-html-report', action='store_true', default=False,
        help="do not generate html report.")
    parser.add_argument(
        '--html-report-name',
        help="specify html report name, only effective when generating html report.")
    parser.add_argument(
        '--html-report-template',
        help="specify html report template path.")
    parser.add_argument(
        '--log-level', default='INFO',
        help="Specify logging level, default is INFO.")
    parser.add_argument(
        '--log-file',
        help="Write logs to specified file path.")
    parser.add_argument(
        '--dot-env-path',
        help="Specify .env file path, which is useful for keeping production credentials.")
    parser.add_argument(
        '--failfast', action='store_true', default=False,
        help="Stop the test run on the first error or failure.")
    parser.add_argument(
        '--startproject',
        help="Specify new project name.")
    parser.add_argument(
        '--validate', nargs='*',
        help="Validate JSON testset format.")
    parser.add_argument(
        '--prettify', nargs='*',
        help="Prettify JSON testset format.")

    args = parser.parse_args()
    logger.setup_logger(args.log_level, args.log_file)

    if is_py2:
        logger.log_warning(get_python2_retire_msg())

    if args.version:
        logger.color_print("{}".format(__version__), "GREEN")
        exit(0)

    if args.validate:
        validate_json_file(args.validate)
        exit(0)
    if args.prettify:
        prettify_json_file(args.prettify)
        exit(0)

    project_name = args.startproject
    if project_name:
        project_path = os.path.join(os.getcwd(), project_name)
        create_scaffold(project_path)
        exit(0)

    runner = HttpRunner(failfast=args.failfast, dot_env_path=args.dot_env_path).run(args.testset_paths)

    if not args.no_html_report:
        runner.gen_html_report(
            html_report_name=args.html_report_name,
            html_report_template=args.html_report_template
        )

    summary = runner.summary
    print_output(summary["output"])
    return 0 if summary["success"] else 1
Ejemplo n.º 15
0
 def handle(self, *args, **options):
     if options['version']:
         logger.color_print("{}".format(__version__), "GREEN")
         exit(0)
Ejemplo n.º 16
0
def runTest():
    """ API test: parse command line options and run commands.
    """
    parser = argparse.ArgumentParser(
        description=
        'YDH HTTP test runner, not just about api test and load test.')

    parser.add_argument('testset_paths', nargs='*', help="testset file path")
    parser.add_argument(
        '--html-report-name',
        help=
        "specify html report name, only effective when generating html report."
    )
    parser.add_argument('--html-report-template',
                        help="specify html report template path.")
    parser.add_argument('--log-level',
                        default='INFO',
                        help="Specify logging level, default is INFO.")
    parser.add_argument(
        '--env',
        nargs='*',
        choices=['develop', 'master', 'release', 'gray', 'production'],
        help="environment")
    parser.add_argument('--testcases',
                        nargs='*',
                        help="specified the testcase name to run")

    parser.add_argument('--target-dirs',
                        nargs='*',
                        help="specified directory to run")

    args = parser.parse_args()
    logger.setup_logger(args.log_level)

    logger.color_print("specified testcase:{}".format(args.testcases))

    #若指定参数优先,则优先覆盖为参数值,否则从ini文件中读取
    env_list = []
    if args.env:
        Env.init_require_envs(args.env)
        env_list = args.env
    else:
        Env.init_require_envs(Env.target_env_list)
        env_list = Env.target_env_list
    logger.color_print("environment:{}".format(env_list))

    #解析依赖路径
    if not args.testset_paths:
        logger.log_info("Reading testcase from conf/setting.ini")
        test_dep_dict, test_path_dict = dependency_parser.load_test_dependency_map_by_path(
            os.path.join(ROOT_DIR, Config.testcase_root_path,
                         Config.testcase_files_path,
                         Config.testcase_dep_parse_dir))

    else:
        test_dep_dict, test_path_dict = dependency_parser.load_test_dependency_map_by_path(
            args.testset_paths)
        logger.log_info("Reading testcase from argument")

    #提取完整子路径
    testcase_dependency = dependency_parser.get_all_dep_paths_with_separator(
        test_dep_dict, '/')
    valid_full_testcase_dependency = dependency_parser.extract_full_dep_paths(
        testcase_dependency)

    logger.color_print("test_dep_dict(len is {}):\n{}".format(
        len(test_dep_dict), test_dep_dict))
    logger.color_print("test_path_dict(len is {}): \n{}".format(
        len(test_path_dict), test_path_dict))
    logger.color_print("testcase_dependency(len is {}):\n{}".format(
        len(testcase_dependency), testcase_dependency))
    logger.color_print("valid_full_testcase_dependency(len is {}):\n{}".format(
        len(valid_full_testcase_dependency), valid_full_testcase_dependency))

    #生成可视化依赖关系图,包含:1)每条完整最长依赖路径   2)一张图for Overall
    if Config.debug_output_enable:
        overall_png = 'Overall.png'
        reversed_graph_overall = dependency_parser.convert_to_reversed_std_graph(
            test_dep_dict)
        dependency_pic_path = os.path.join(ROOT_DIR, Config.debug_root_path,
                                           Config.dependency_pic_path)
        pic_saved_path = os.path.join(dependency_pic_path, overall_png)
        if not os.path.exists(dependency_pic_path):
            os.makedirs(dependency_pic_path)

        dependency_parser.save_graph(reversed_graph_overall, pic_saved_path)

        std_graph = dependency_parser.get_std_graphs_dict_from_full_path(
            valid_full_testcase_dependency)
        for key, graph in std_graph.items():
            reversed_graph = dependency_parser.convert_to_reversed_std_graph(
                graph)
            file_name = str(key) + '.png'
            file_path = os.path.join(dependency_pic_path, file_name)
            dependency_parser.save_graph(reversed_graph, file_path)

    #依赖根节点测试
    testcase_to_root = 'GetToken'
    login_depend_root = get_login_depend_root(testcase_to_root,
                                              valid_full_testcase_dependency)
    logger.color_print('get_login_depend function test:  {} ---> {}'.format(
        testcase_to_root, login_depend_root))

    #从完整子路径中,找出依赖最深的用例名。例如1/2/4,则提取出1
    to_run_list = []
    test_login_depend_dict = defaultdict(list)
    for testcase, path in test_path_dict.items():
        assert testcase + '.yml' == os.path.basename(
            path
        ), 'testcase_name and filename NOT consistent! testcase:{} != file_name:{},\n Check the file in abs_path:{}'.format(
            testcase, os.path.basename(path), path)
        for test in valid_full_testcase_dependency:
            if testcase == test.split('/')[1]:
                to_run_list.append(test_path_dict[testcase])
                if not test_login_depend_dict[testcase]:
                    test_login_depend_dict[testcase] = test.split('/')[-1]
                else:
                    assert test_login_depend_dict[testcase] == test.split(
                        '/'
                    )[-1], '!!!!!!!Error:One testcase depend on different login'
                    #报错条件:一个用例依赖不同登录视为异常, 如CorpV2LogisticsDeliver,依赖路径上最后的依赖节点只应该为CorpAuthentication

    logger.color_print(
        "login_depend_dict is:\n{}".format(test_login_depend_dict))
    logger.color_print('testcase list to run(len:{}):\n{}'.format(
        len(to_run_list), to_run_list))

    to_run_set = list(set(to_run_list))
    logger.color_print("Remove duplicates(len:{}):\n{}".format(
        len(to_run_set), to_run_set))
    if args.testcases:
        logger.color_print('The specified testcase to run is:{}'.format(
            args.testcases))

    #切换环境,替换IP
    for target_env in env_list:
        Env.reload_env(target_env)

        ydh_testresult = YDHHtmlTestResult()

        login_session_dict, global_variables = get_login_session_variabls(
            test_path_dict,
            valid_full_dep_path=valid_full_testcase_dependency,
            test_result=ydh_testresult)
        logger.color_print(
            "Login Session Data:\n{}".format(login_session_dict))

        http_client_session_dict = dict()
        if args.testcases:
            logger.color_print("specified testcases is:{}".format(
                args.testcases))
            if isinstance(args.testcases, (list, set)):  # 若参数中指定用例名,则只跑指定的用例
                for testcase in args.testcases:
                    run_ydhrunner(
                        testcase=testcase,
                        valid_full_testcase_dependency=
                        valid_full_testcase_dependency,
                        test_path_dict=test_path_dict,
                        http_client_session_dict=http_client_session_dict,
                        test_result=ydh_testresult,
                        global_variables=global_variables)
        elif args.target_dirs:
            logger.color_print("specified target_dirs is:{}".format(
                args.target_dirs))
            for target_dir in args.target_dirs:
                target_dir_files = os.listdir(
                    os.path.join(ROOT_DIR, target_dir))
                for test_file in target_dir_files:
                    for test, file_path in test_path_dict.items():
                        if os.path.basename(file_path) == test_file:
                            run_ydhrunner(testcase=test,
                                          valid_full_testcase_dependency=
                                          valid_full_testcase_dependency,
                                          test_path_dict=test_path_dict,
                                          http_client_session_dict=
                                          http_client_session_dict,
                                          test_result=ydh_testresult,
                                          global_variables=global_variables)

        else:
            for test_file in to_run_set:
                for test, file_path in test_path_dict.items():
                    if file_path == test_file:
                        run_ydhrunner(
                            testcase=test,
                            valid_full_testcase_dependency=
                            valid_full_testcase_dependency,
                            test_path_dict=test_path_dict,
                            http_client_session_dict=http_client_session_dict,
                            test_result=ydh_testresult,
                            global_variables=global_variables)

        ydh_testresult.render_html_report()
Ejemplo n.º 17
0
def main():
    clean_redis()

    runTest()

    logger.color_print("End of main")
Ejemplo n.º 18
0
 def startTest(self, test):
     """ add start test time """
     super(HtmlTestResult, self).startTest(test)
     logger.color_print(test.shortDescription(), "yellow")