Пример #1
0
def prettify_json_file(file_list):
    """ prettify 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 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))
Пример #2
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):
        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)
    else:
        # '' or other suffix
        logger.color_print("file type should be YAML/JSON/Python, exit.",
                           "RED")
        sys.exit(1)

    return locustfile_path
Пример #3
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)

    file_foder_path = os.path.dirname(json_file_abs_path)
    if not os.path.isdir(file_foder_path):
        os.makedirs(file_foder_path)

    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=(',', ':'),
                                   encoding="utf8",
                                   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")
Пример #4
0
 def create_file(path, file_content=""):
     with open(path, 'w') as f:
         f.write(file_content)
     msg = "created file: {}".format(path)
     logger.color_print(msg, "BLUE")
Пример #5
0
 def create_folder(path):
     os.makedirs(path)
     msg = "created folder: {}".format(path)
     logger.color_print(msg, "BLUE")
Пример #6
0
def create_scaffold(project_name):
    """ create scaffold with specified project name.
    """
    if os.path.isdir(project_name):
        logger.log_warning(
            u"Folder {} exists, please specify a new folder name.".format(
                project_name))
        return

    logger.color_print("Start to create new project: {}".format(project_name),
                       "GREEN")
    logger.color_print("CWD: {}\n".format(os.getcwd()), "BLUE")

    def create_folder(path):
        os.makedirs(path)
        msg = "created folder: {}".format(path)
        logger.color_print(msg, "BLUE")

    def create_file(path, file_content=""):
        with open(path, 'w') as f:
            f.write(file_content)
        msg = "created file: {}".format(path)
        logger.color_print(msg, "BLUE")

    demo_api_content = """
name: demo api
variables:
    var1: value1
    var2: value2
request:
    url: /api/path/$var1
    method: POST
    headers:
        Content-Type: "application/json"
    json:
        key: $var2
validate:
    - eq: ["status_code", 200]
"""
    demo_testcase_content = """
config:
    name: "demo testcase"
    variables:
        device_sn: "ABC"
        username: ${ENV(USERNAME)}
        password: ${ENV(PASSWORD)}
    base_url: "http://127.0.0.1:5000"

teststeps:
-
    name: demo step 1
    api: path/to/api1.yml
    variables:
        user_agent: 'iOS/10.3'
        device_sn: $device_sn
    extract:
        - token: content.token
    validate:
        - eq: ["status_code", 200]
-
    name: demo step 2
    api: path/to/api2.yml
    variables:
        token: $token
"""
    demo_testsuite_content = """
config:
    name: "demo testsuite"
    variables:
        device_sn: "XYZ"
    base_url: "http://127.0.0.1:5000"

testcases:
-
    name: call demo_testcase with data 1
    testcase: path/to/demo_testcase.yml
    variables:
        device_sn: $device_sn
-
    name: call demo_testcase with data 2
    testcase: path/to/demo_testcase.yml
    variables:
        device_sn: $device_sn
"""
    ignore_content = "\n".join([
        ".env", "reports/*", "__pycache__/*", "*.pyc", ".python-version",
        "logs/*"
    ])
    demo_debugtalk_content = """
import time

def sleep(n_secs):
    time.sleep(n_secs)
"""
    demo_env_content = "\n".join(["USERNAME=leolee", "PASSWORD=123456"])

    create_folder(project_name)
    create_folder(os.path.join(project_name, "api"))
    create_folder(os.path.join(project_name, "testcases"))
    create_folder(os.path.join(project_name, "testsuites"))
    create_folder(os.path.join(project_name, "reports"))
    create_file(os.path.join(project_name, "api", "demo_api.yml"),
                demo_api_content)
    create_file(os.path.join(project_name, "testcases", "demo_testcase.yml"),
                demo_testcase_content)
    create_file(os.path.join(project_name, "testsuites", "demo_testsuite.yml"),
                demo_testsuite_content)
    create_file(os.path.join(project_name, "debugtalk.py"),
                demo_debugtalk_content)
    create_file(os.path.join(project_name, ".env"), demo_env_content)
    create_file(os.path.join(project_name, ".gitignore"), ignore_content)
Пример #7
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 YAML/JSON api/testcase/testsuite 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:
        for validate_path in args.validate:
            try:
                color_print("validate test file: {}".format(validate_path), "GREEN")
                load_cases(validate_path, args.dot_env_path)
            except exceptions.MyBaseError as ex:
                log_error(str(ex))
                continue

        color_print("done!", "BLUE")
        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")
        sentry_sdk.capture_exception(ex)
        err_code = 1

    sys.exit(err_code)
Пример #8
0
 def startTest(self, test):
     """ add start test time """
     super(HtmlTestResult, self).startTest(test)
     logger.color_print(test.shortDescription(), "yellow")