Пример #1
0
def _load_testcase(raw_testcase, project_mapping):
    """ load testcase/testsuite with api/testcase references

    Args:
        raw_testcase (list): raw testcase content loaded from JSON/YAML file:
            [
                # config part
                {
                    "config": {
                        "name": "",
                        "def": "suite_order()",
                        "request": {}
                    }
                },
                # teststeps part
                {
                    "test": {...}
                },
                {
                    "test": {...}
                }
            ]
        project_mapping (dict): project_mapping

    Returns:
        dict: loaded testcase content
            {
                "config": {},
                "teststeps": [teststep11, teststep12]
            }

    """
    loaded_testcase = {"config": {}, "teststeps": []}

    for item in raw_testcase:
        # TODO: add json schema validation
        if not isinstance(item, dict) or len(item) != 1:
            raise exceptions.FileFormatError(
                "Testcase format error: {}".format(item))

        key, test_block = item.popitem()
        if not isinstance(test_block, dict):
            raise exceptions.FileFormatError(
                "Testcase format error: {}".format(item))

        if key == "config":
            loaded_testcase["config"].update(test_block)

        elif key == "test":
            loaded_testcase["teststeps"].extend(
                _load_teststeps(test_block, project_mapping))

        else:
            logger.log_warning(
                "unexpected block key: {}. block key should only be 'config' or 'test'."
                .format(key))

    return loaded_testcase
Пример #2
0
    def _check_format(file_path, content):
        """ check testcase format if valid
        """
        if not content:
            # testcase file content is empty
            err_msg = u"Testcase file content is empty: {}".format(file_path)
            logger.log_error(err_msg)
            raise exceptions.FileFormatError(err_msg)

        elif not isinstance(content, (list, dict)):
            # testcase file content does not match testcase format
            err_msg = u"Testcase file content format invalid: {}".format(file_path)
            logger.log_error(err_msg)
            raise exceptions.FileFormatError(err_msg)
Пример #3
0
def load_dot_env_file(path):
    """ load .env file
    """
    if not path:
        path = os.path.join(os.getcwd(), ".env")
        if not os.path.isfile(path):
            logger.log_debug(".env file not exist: {}".format(path))
            return {}
    else:
        if not os.path.isfile(path):
            raise exceptions.FileNotFound(
                "env file not exist: {}".format(path))

    logger.log_info("Loading environment variables from {}".format(path))
    env_variables_mapping = {}
    with io.open(path, 'r', encoding='utf-8') as fp:
        for line in fp:
            if "=" in line:
                variable, value = line.split("=")
            elif ":" in line:
                variable, value = line.split(":")
            else:
                raise exceptions.FileFormatError(".env format error")

            env_variables_mapping[variable.strip()] = value.strip()

    return env_variables_mapping
Пример #4
0
def convert_jmespath(raw: Text) -> Text:
    # content.xx/json.xx => body.xx
    if raw.startswith("content"):
        raw = f"body{raw[len('content'):]}"
    elif raw.startswith("json"):
        raw = f"body{raw[len('json'):]}"

    raw_list = []
    for item in raw.split("."):
        if "-" in item:
            # add quotes for field with separator
            # e.g. headers.Content-Type => headers."Content-Type"
            item = item.strip('"')
            raw_list.append(f'"{item}"')
        elif item.isdigit():
            # convert lst.0.name to lst[0].name
            if len(raw_list) == 0:
                raise exceptions.FileFormatError(
                    f"Invalid jmespath: {raw}, jmespath should startswith headers/body/status_code/cookies"
                )

            last_item = raw_list.pop()
            item = f"{last_item}[{item}]"
            raw_list.append(item)
        else:
            raw_list.append(item)

    return ".".join(raw_list)
Пример #5
0
def __extend_with_testcase_ref(raw_testinfo):
    """ extend with test_case reference
    """
    testcase_path = raw_testinfo["test_case"]

    if testcase_path not in tests_def_mapping["testcases"]:
        # make compatible with Windows/Linux
        pwd = get_project_working_directory()
        testcase_path = os.path.join(pwd, *testcase_path.split("/"))
        loaded_testcase = load_file(testcase_path)

        if isinstance(loaded_testcase, list):
            # make compatible with version < 2.2.0
            testcase_dict = load_testcase(loaded_testcase)
        elif isinstance(loaded_testcase,
                        dict) and "teststeps" in loaded_testcase:
            # format version 2, implemented in 2.2.0
            testcase_dict = load_testcase_v2(loaded_testcase)
        else:
            raise exceptions.FileFormatError(
                "Invalid format test_case: {}".format(testcase_path))

        tests_def_mapping["testcases"][testcase_path] = testcase_dict
    else:
        testcase_dict = tests_def_mapping["testcases"][testcase_path]

    raw_testinfo["testcase_def"] = testcase_dict
Пример #6
0
def convert_extractors(extractors: Union[List, Dict]) -> Dict:
    """ convert extract list(v2) to dict(v3)

    Args:
        extractors: [{"varA": "content.varA"}, {"varB": "json.varB"}]

    Returns:
        {"varA": "body.varA", "varB": "body.varB"}

    """
    v3_extractors: Dict = {}

    if isinstance(extractors, List):
        for extractor in extractors:
            for k, v in extractor.items():
                v3_extractors[k] = v
    elif isinstance(extractors, Dict):
        v3_extractors = extractors
    else:
        raise exceptions.FileFormatError(f"Invalid extractor: {extractors}")

    for k, v in v3_extractors.items():
        v3_extractors[k] = convert_jmespath(v)

    return v3_extractors
Пример #7
0
def load_testcase_file(testcase_file: Text) -> Tuple[Dict, TestCase]:
    """load testcase file and validate with pydantic model"""
    if not os.path.isfile(testcase_file):
        raise exceptions.FileNotFound(
            f"testcase file not exists: {testcase_file}")

    file_suffix = os.path.splitext(testcase_file)[1].lower()
    if file_suffix == ".json":
        testcase_content = _load_json_file(testcase_file)
    elif file_suffix in [".yaml", ".yml"]:
        testcase_content = _load_yaml_file(testcase_file)
    else:
        # '' or other suffix
        raise exceptions.FileFormatError(
            f"testcase file should be YAML/JSON format, invalid testcase file: {testcase_file}"
        )

    try:
        # validate with pydantic TestCase model
        testcase_obj = TestCase.parse_obj(testcase_content)
    except ValidationError as ex:
        err_msg = f"Invalid testcase format: {testcase_file}"
        logger.error(f"{err_msg}\n{ex}")
        raise exceptions.TestCaseFormatError(err_msg)

    testcase_content["config"]["path"] = testcase_file
    testcase_obj.config.path = testcase_file

    return testcase_content, testcase_obj
Пример #8
0
    def load_api_file(file_path):
        """ load api definition from file and store in overall_def_dict["api"]
            api file should be in format below:
                [
                    {
                        "api": {
                            "def": "api_login",
                            "request": {},
                            "validate": []
                        }
                    },
                    {
                        "api": {
                            "def": "api_logout",
                            "request": {},
                            "validate": []
                        }
                    }
                ]
        """
        api_items = FileUtils.load_file(file_path)
        if not isinstance(api_items, list):
            raise exceptions.FileFormatError(
                "API format error: {}".format(file_path))

        for api_item in api_items:
            if not isinstance(api_item, dict) or len(api_item) != 1:
                raise exceptions.FileFormatError(
                    "API format error: {}".format(file_path))

            key, api_dict = api_item.popitem()
            if key != "api" or not isinstance(api_dict,
                                              dict) or "def" not in api_dict:
                raise exceptions.FileFormatError(
                    "API format error: {}".format(file_path))

            api_def = api_dict.pop("def")
            function_meta = parse_function(api_def)
            func_name = function_meta["func_name"]

            if func_name in TestcaseLoader.overall_def_dict["api"]:
                logger.log_warning(
                    "API definition duplicated: {}".format(func_name))

            api_dict["function_meta"] = function_meta
            TestcaseLoader.overall_def_dict["api"][func_name] = api_dict
Пример #9
0
def _check_format(file_path, content):
    '''
    check testcase format if valid
    '''

    if not content:  # empty file
        err_msg = f'Testcase file content is empty: {file_path}'
        logger.log_error(err_msg)
        raise exceptions.FileFormatError(err_msg)
Пример #10
0
def _load_json_file(json_file: Text) -> Dict:
    """load json file and check file content format"""
    with open(json_file, mode="rb") as data_file:
        try:
            json_content = json.load(data_file)
        except json.JSONDecodeError as ex:
            err_msg = f"JSONDecodeError:\nfile: {json_file}\nerror: {ex}"
            raise exceptions.FileFormatError(err_msg)

        return json_content
Пример #11
0
def _check_format(file_path, content):
    '''
    check testcase format if vaild
    '''

    if not content:
        err_msg = f'Testcase file content is empty: {file_path}'
        print(err_msg)
        raise exceptions.FileFormatError(err_msg)
    elif not isinstance(content, (list, dict)):
        err_msg = f'testcase does content format invaild: {file_path}'
Пример #12
0
def load_yaml_file(yaml_file):
    '''
    load yaml file and check file content format
    '''

    with open(yaml_file, 'r', encoding='utf-8') as f:
        yaml_content = yaml.load(f)
        _check_format(yaml_file, yaml_content)
        if not isinstance(yaml_content, dict):
            err_msg = f'YAML file format error: {yaml_file}'
            raise exceptions.FileFormatError(err_msg)
        return yaml_content
Пример #13
0
def _load_json_file(json_file):
    """ load json file and check file content format
    """
    with io.open(json_file, encoding='utf-8') as data_file:
        try:
            json_content = json.load(data_file)
        except json.JSONDecodeError:
            err_msg = f"JSONDecodeError: JSON file format error: {json_file}"
            logger.error(err_msg)
            raise exceptions.FileFormatError(err_msg)

        return json_content
Пример #14
0
def load_json_file(json_file):
    """ load json file and check file content format
    """
    with io.open(json_file, encoding='utf-8') as data_file:
        try:
            json_content = json.load(data_file)
        except exceptions.JSONDecodeError:
            err_msg = u"JSONDecodeError: JSON file format error: {}".format(json_file)
            logger.log_error(err_msg)
            raise exceptions.FileFormatError(err_msg)

        _check_format(json_file, json_content)
        return json_content
Пример #15
0
def load_yaml_file(yaml_file_path):
    '''
    load yaml file and check file content format
    '''

    with open(yaml_file_path, 'r', encoding='utf-8') as stream:
        yaml_content = yaml.load(stream)
        _check_format(yaml_file_path, yaml_content)
        if not isinstance(yaml_content, (list, dict)):
            err_msg = f'YAML file format error: {yaml_file_path}'
            logger.log_error(err_msg)
            raise exceptions.FileFormatError(err_msg)
        return yaml_content
Пример #16
0
def load_json_file(json_file_path):
    '''
    load json file and check file content format
    '''

    with open(json_file_path, 'r', encoding='utf-8') as data_file:
        try:
            json_content = json.load(data_file)
        except exceptions.JSONDecodeError:
            err_msg = f'JSONDecodeError: JSON file format error: {json_file_path}'
            logger.log_error(err_msg)
            raise exceptions.FileFormatError(err_msg)
        _check_format(json_file_path, json_content)
        return json_content
Пример #17
0
def __make(tests_path: Text) -> List:
    test_files = []
    if os.path.isdir(tests_path):
        files_list = load_folder_files(tests_path)
        test_files.extend(files_list)
    elif os.path.isfile(tests_path):
        test_files.append(tests_path)
    else:
        raise exceptions.TestcaseNotFound(f"Invalid tests path: {tests_path}")

    testcase_path_list = []
    for test_file in test_files:
        try:
            test_content = load_test_file(test_file)
            test_content.setdefault("config", {})["path"] = test_file
        except (exceptions.FileNotFound, exceptions.FileFormatError) as ex:
            logger.warning(ex)
            continue

        # testcase
        if "teststeps" in test_content:
            try:
                testcase_file = make_testcase(test_content)
            except exceptions.TestCaseFormatError:
                continue

            testcase_path_list.append(testcase_file)

        # testsuite
        elif "testcases" in test_content:
            try:
                testcase_files = make_testsuite(test_content)
            except exceptions.TestSuiteFormatError:
                continue

            testcase_path_list.extend(testcase_files)

        # invalid format
        else:
            raise exceptions.FileFormatError(
                f"test file is neither testcase nor testsuite: {test_file}"
            )

    if not testcase_path_list:
        logger.warning(f"No valid testcase generated on {tests_path}")
        return []

    return testcase_path_list
Пример #18
0
def __make(tests_path: Text) -> NoReturn:
    """ make testcase(s) with testcase/testsuite/folder absolute path
        generated pytest file path will be cached in make_files_cache_set

    Args:
        tests_path: should be in absolute path

    """
    test_files = []
    if os.path.isdir(tests_path):
        files_list = load_folder_files(tests_path)
        test_files.extend(files_list)
    elif os.path.isfile(tests_path):
        test_files.append(tests_path)
    else:
        raise exceptions.TestcaseNotFound(f"Invalid tests path: {tests_path}")

    for test_file in test_files:
        try:
            test_content = load_test_file(test_file)
        except (exceptions.FileNotFound, exceptions.FileFormatError) as ex:
            logger.warning(ex)
            continue

        # api in v2 format, convert to v3 testcase
        if "request" in test_content:
            test_content = ensure_testcase_v3_api(test_content)

        test_content.setdefault("config", {})["path"] = test_file

        # testcase
        if "teststeps" in test_content:
            try:
                __make_testcase(test_content)
            except exceptions.TestCaseFormatError:
                continue

        # testsuite
        elif "testcases" in test_content:
            try:
                __make_testsuite(test_content)
            except exceptions.TestSuiteFormatError:
                continue

        # invalid format
        else:
            raise exceptions.FileFormatError(
                f"test file is neither testcase nor testsuite: {test_file}")
Пример #19
0
def load_dot_env_file(path):
    """ load .env file

    Args:
        path (str): .env file path.
            If path is None, it will find .env file in current working directory.

    Returns:
        dict: environment variables mapping

            {
                "UserName": "******",
                "Password": "******",
                "PROJECT_KEY": "ABCDEFGH"
            }

    Raises:
        exceptions.FileNotFound: If specified env file is not exist.
        exceptions.FileFormatError: If env file format is invalid.

    """
    if not path:
        path = os.path.join(os.getcwd(), ".env")
        if not os.path.isfile(path):
            logger.log_debug(".env file not exist: {}".format(path))
            return {}
    else:
        if not os.path.isfile(path):
            raise exceptions.FileNotFound(
                "env file not exist: {}".format(path))

    logger.log_info("Loading environment variables from {}".format(path))
    env_variables_mapping = {}
    with io.open(path, 'r', encoding='utf-8') as fp:
        for line in fp:
            if "=" in line:
                variable, value = line.split("=")
            elif ":" in line:
                variable, value = line.split(":")
            else:
                raise exceptions.FileFormatError(".env format error")

            env_variables_mapping[variable.strip()] = value.strip()

    project_mapping["env"] = env_variables_mapping
    return env_variables_mapping
Пример #20
0
def load_test_file(test_file: Text) -> Dict:
    """load testcase/testsuite file content"""
    if not os.path.isfile(test_file):
        raise exceptions.FileNotFound(f"test file not exists: {test_file}")

    file_suffix = os.path.splitext(test_file)[1].lower()
    if file_suffix == ".json":
        test_file_content = _load_json_file(test_file)
    elif file_suffix in [".yaml", ".yml"]:
        test_file_content = _load_yaml_file(test_file)
    else:
        # '' or other suffix
        raise exceptions.FileFormatError(
            f"testcase/testsuite file should be YAML/JSON format, invalid format file: {test_file}"
        )

    return test_file_content
Пример #21
0
def load_dot_env_file():
    """ load .env file, .env file should be located in project working directory by default.
        If dot_env_path is specified, it will be loaded instead.

    Returns:
        dict: environment variables mapping

            {
                "UserName": "******",
                "Password": "******",
                "PROJECT_KEY": "ABCDEFGH"
            }

    Raises:
        exceptions.FileFormatError: If env file format is invalid.

    """
    path = dot_env_path or os.path.join(project_working_directory, ".env")
    if not os.path.isfile(path):
        if dot_env_path:
            logger.log_error(".env file not exist: {}".format(dot_env_path))
            sys.exit(1)
        else:
            logger.log_debug(
                ".env file not exist in: {}".format(project_working_directory))
            return {}

    logger.log_info("Loading environment variables from {}".format(path))
    env_variables_mapping = {}
    with io.open(path, 'r', encoding='utf-8') as fp:
        for line in fp:
            # maxsplit=1
            if "=" in line:
                variable, value = line.split("=", 1)
            elif ":" in line:
                variable, value = line.split(":", 1)
            else:
                raise exceptions.FileFormatError(".env format error")

            env_variables_mapping[variable.strip()] = value.strip()

    project_mapping["env"] = env_variables_mapping
    utils.set_os_environ(env_variables_mapping)

    return env_variables_mapping
Пример #22
0
def load_dot_env_file(dot_env_path: Text) -> Dict:
    """load .env file.

    Args:
        dot_env_path (str): .env file path

    Returns:
        dict: environment variables mapping

            {
                "UserName": "******",
                "Password": "******",
                "PROJECT_KEY": "ABCDEFGH"
            }

    Raises:
        exceptions.FileFormatError: If .env file format is invalid.

    """
    if not os.path.isfile(dot_env_path):
        return {}

    logger.info(f"Loading environment variables from {dot_env_path}")
    env_variables_mapping = {}

    with open(dot_env_path, mode="rb") as fp:
        for line in fp:
            # maxsplit=1
            line = line.strip()
            if not len(line) or line.startswith(b"#"):
                continue
            if b"=" in line:
                variable, value = line.split(b"=", 1)
            elif b":" in line:
                variable, value = line.split(b":", 1)
            else:
                raise exceptions.FileFormatError(".env format error")

            env_variables_mapping[variable.strip().decode(
                "utf-8")] = value.strip().decode("utf-8")

    utils.set_os_environ(env_variables_mapping)
    return env_variables_mapping
Пример #23
0
def load_dot_env_file(dot_env_path):
    """ load .env file.

    Args:
        dot_env_path (str): .env file path

    Returns:
        dict: environment variables mapping

            {
                "UserName": "******",
                "Password": "******",
                "PROJECT_KEY": "ABCDEFGH"
            }

    Raises:
        exceptions.FileFormatError: If .env file format is invalid.

    """
    if not os.path.isfile(dot_env_path):
        return {}

    logger.log_info(
        "Loading environment variables from {}".format(dot_env_path))
    env_variables_mapping = {}

    with io.open(dot_env_path, 'r', encoding='utf-8') as fp:
        for line in fp:
            # maxsplit=1
            if "=" in line:
                variable, value = line.split("=", 1)
            elif ":" in line:
                variable, value = line.split(":", 1)
            elif line.startswith("#") or line.startswith("\n"):
                pass
            else:
                raise exceptions.FileFormatError(".env format error")

            env_variables_mapping[variable.strip()] = value.strip()

    utils.set_os_environ(env_variables_mapping)
    return env_variables_mapping
Пример #24
0
def load_env_file():
    '''
    load .env file, .env file should be located in project working directory.
    Returns:
        dict: enviroment variables mapping
            {
                'username':'******',
                'password':'******',
                'PROJECT_KEY':'ABCDEFGH'
            }
    Raises:
        exceptions.FileFormatError: If env file format is invalid.
    '''

    path = os.path.join(project_working_directory, '.env')
    if not os.path.isfile(path):
        logger.log_debug(
            f'.env file not exist in: {project_working_directory}')
        return {}

    logger.log_info(f'Loading enviroment variables from {path}')
    env_variables_mapping = {}
    with open(path, 'r', encoding='utf-8') as fp:
        for line in fp:
            if '=' in line:
                variable, value = line.split('=')
            elif ':' in line:
                variable, value = line.split(':')
            else:
                raise exceptions.FileFormatError('.env format error')

            env_variables_mapping[variable.strip()] = value.strip()

    project_mapping['env'] = env_variables_mapping
    utils.set_os_environ(env_variables_mapping)

    return env_variables_mapping
Пример #25
0
def __make(tests_path: Text) -> NoReturn:
    """ make testcase(s) with testcase/testsuite/folder absolute path
        generated pytest file path will be cached in pytest_files_made_cache_mapping

    Args:
        tests_path: should be in absolute path

    """
    test_files = []
    if os.path.isdir(tests_path):
        files_list = load_folder_files(tests_path)
        test_files.extend(files_list)
    elif os.path.isfile(tests_path):
        test_files.append(tests_path)
    else:
        raise exceptions.TestcaseNotFound(f"Invalid tests path: {tests_path}")

    for test_file in test_files:
        if test_file.lower().endswith("_test.py"):
            pytest_files_run_set.add(test_file)
            continue

        try:
            test_content = load_test_file(test_file)
        except (exceptions.FileNotFound, exceptions.FileFormatError) as ex:
            logger.warning(ex)
            continue

        if not isinstance(test_content, Dict):
            raise exceptions.FileFormatError(
                f"test content not in dict format: {test_content}")

        # api in v2 format, convert to v3 testcase
        if "request" in test_content and "name" in test_content:
            test_content = ensure_testcase_v3_api(test_content)

        if "config" not in test_content:
            raise exceptions.FileFormatError(
                f"miss config part in testcase/testsuite: {test_content}")

        test_content.setdefault("config", {})["path"] = test_file

        # testcase
        if "teststeps" in test_content:
            try:
                testcase_pytest_path = make_testcase(test_content)
                pytest_files_run_set.add(testcase_pytest_path)
            except exceptions.TestCaseFormatError:
                continue

        # testsuite
        elif "testcases" in test_content:
            try:
                make_testsuite(test_content)
            except exceptions.TestSuiteFormatError:
                continue

        # invalid format
        else:
            logger.warning(
                f"skip invalid testcase/testsuite file: {test_file}")
Пример #26
0
def load_test_file(path):
    """ load test file, file maybe test_case/testsuite/api

    Args:
        path (str): test file path

    Returns:
        dict: loaded test content

            # api
            {
                "path": path,
                "type": "api",
                "name": "",
                "request": {}
            }

            # test_case
            {
                "path": path,
                "type": "test_case",
                "config": {},
                "teststeps": []
            }

            # testsuite
            {
                "path": path,
                "type": "testsuite",
                "config": {},
                "testcases": {}
            }

    """
    raw_content = load_file(path)

    if isinstance(raw_content, dict):

        if "testcases" in raw_content:
            # file_type: testsuite
            loaded_content = load_testsuite(raw_content)
            loaded_content["path"] = path
            loaded_content["type"] = "testsuite"

        elif "teststeps" in raw_content:
            # file_type: test_case (format version 2)
            loaded_content = load_testcase_v2(raw_content)
            loaded_content["path"] = path
            loaded_content["type"] = "test_case"

        elif "request" in raw_content:
            # file_type: api
            JsonSchemaChecker.validate_api_format(raw_content)
            loaded_content = raw_content
            loaded_content["path"] = path
            loaded_content["type"] = "api"

        else:
            # invalid format
            raise exceptions.FileFormatError("Invalid test file format!")

    elif isinstance(raw_content, list) and len(raw_content) > 0:
        # file_type: test_case
        # make compatible with version < 2.2.0
        loaded_content = load_testcase(raw_content)
        loaded_content["path"] = path
        loaded_content["type"] = "test_case"

    else:
        # invalid format
        raise exceptions.FileFormatError("Invalid test file format!")

    return loaded_content
Пример #27
0
def load_testsuite(raw_testsuite):
    """ load testsuite with test_case references.
        support two different formats.

    Args:
        raw_testsuite (dict): raw testsuite content loaded from JSON/YAML file:
            # version 1, compatible with version < 2.2.0
            {
                "config": {
                    "name": "xxx",
                    "variables": {}
                }
                "testcases": {
                    "testcase1": {
                        "test_case": "/path/to/test_case",
                        "variables": {...},
                        "parameters": {...}
                    },
                    "testcase2": {}
                }
            }

            # version 2, implemented in 2.2.0
            {
                "config": {
                    "name": "xxx",
                    "variables": {}
                }
                "testcases": [
                    {
                        "name": "testcase1",
                        "test_case": "/path/to/test_case",
                        "variables": {...},
                        "parameters": {...}
                    },
                    {}
                ]
            }

    Returns:
        dict: loaded testsuite content
            {
                "config": {},
                "testcases": [testcase1, testcase2]
            }

    """
    raw_testcases = raw_testsuite["testcases"]

    if isinstance(raw_testcases, dict):
        # format version 1, make compatible with version < 2.2.0
        JsonSchemaChecker.validate_testsuite_v1_format(raw_testsuite)
        raw_testsuite["testcases"] = {}
        for name, raw_testcase in raw_testcases.items():
            __extend_with_testcase_ref(raw_testcase)
            raw_testcase.setdefault("name", name)
            raw_testsuite["testcases"][name] = raw_testcase

    elif isinstance(raw_testcases, list):
        # format version 2, implemented in 2.2.0
        JsonSchemaChecker.validate_testsuite_v2_format(raw_testsuite)
        raw_testsuite["testcases"] = {}
        for raw_testcase in raw_testcases:
            __extend_with_testcase_ref(raw_testcase)
            testcase_name = raw_testcase["name"]
            raw_testsuite["testcases"][testcase_name] = raw_testcase

    else:
        # invalid format
        raise exceptions.FileFormatError("Invalid testsuite format!")

    return raw_testsuite
Пример #28
0
def _load_test_file(file_path):
    """ load testcase file or testsuite file

    Args:
        file_path (str): absolute valid file path. file_path should be in the following format:

            [
                {
                    "config": {
                        "name": "",
                        "def": "suite_order()",
                        "request": {}
                    }
                },
                {
                    "test": {
                        "name": "add product to cart",
                        "api": "api_add_cart()",
                        "validate": []
                    }
                },
                {
                    "test": {
                        "name": "add product to cart",
                        "suite": "create_and_check()",
                        "validate": []
                    }
                },
                {
                    "test": {
                        "name": "checkout cart",
                        "request": {},
                        "validate": []
                    }
                }
            ]

    Returns:
        dict: testcase dict
            {
                "config": {},
                "teststeps": [teststep11, teststep12]
            }

    """
    testcase = {"config": {}, "teststeps": []}

    for item in load_file(file_path):
        # TODO: add json schema validation
        if not isinstance(item, dict) or len(item) != 1:
            raise exceptions.FileFormatError(
                "Testcase format error: {}".format(file_path))

        key, test_block = item.popitem()
        if not isinstance(test_block, dict):
            raise exceptions.FileFormatError(
                "Testcase format error: {}".format(file_path))

        if key == "config":
            testcase["config"].update(test_block)

        elif key == "test":

            def extend_api_definition(block):
                ref_call = block["api"]
                def_block = _get_block_by_name(ref_call, "def-api")
                _extend_block(block, def_block)

            # reference api
            if "api" in test_block:
                extend_api_definition(test_block)
                testcase["teststeps"].append(test_block)

            # reference testcase
            elif "suite" in test_block:  # TODO: replace suite with testcase
                ref_call = test_block["suite"]
                block = _get_block_by_name(ref_call, "def-testcase")
                # TODO: bugfix lost block config variables
                for teststep in block["teststeps"]:
                    if "api" in teststep:
                        extend_api_definition(teststep)
                    testcase["teststeps"].append(teststep)

            # define directly
            else:
                testcase["teststeps"].append(test_block)

        else:
            logger.log_warning(
                "unexpected block key: {}. block key should only be 'config' or 'test'."
                .format(key))

    return testcase
Пример #29
0
    def load_test_file(file_path):
        """ load testcase file or suite file
        @param file_path: absolute valid file path
            file_path should be in format below:
                [
                    {
                        "config": {
                            "name": "",
                            "def": "suite_order()",
                            "request": {}
                        }
                    },
                    {
                        "test": {
                            "name": "add product to cart",
                            "api": "api_add_cart()",
                            "validate": []
                        }
                    },
                    {
                        "test": {
                            "name": "checkout cart",
                            "request": {},
                            "validate": []
                        }
                    }
                ]
        @return testset dict
            {
                "config": {},
                "testcases": [testcase11, testcase12]
            }
        """
        testset = {
            "config": {
                "path": file_path
            },
            "testcases": []  # TODO: rename to tests
        }
        for item in FileUtils.load_file(file_path):
            if not isinstance(item, dict) or len(item) != 1:
                raise exceptions.FileFormatError(
                    "Testcase format error: {}".format(file_path))

            key, test_block = item.popitem()
            if not isinstance(test_block, dict):
                raise exceptions.FileFormatError(
                    "Testcase format error: {}".format(file_path))

            if key == "config":
                testset["config"].update(test_block)

            elif key == "test":
                if "api" in test_block:
                    ref_call = test_block["api"]
                    def_block = TestcaseLoader._get_block_by_name(
                        ref_call, "api")
                    TestcaseLoader._override_block(def_block, test_block)
                    testset["testcases"].append(test_block)
                elif "suite" in test_block:
                    ref_call = test_block["suite"]
                    block = TestcaseLoader._get_block_by_name(
                        ref_call, "suite")
                    testset["testcases"].extend(block["testcases"])
                else:
                    testset["testcases"].append(test_block)

            else:
                logger.log_warning(
                    "unexpected block key: {}. block key should only be 'config' or 'test'."
                    .format(key))

        return testset
Пример #30
0
def _load_test_file(file_path):
    '''
    load testcase file or testsuite file
    Args:
        file_path (str): absolute valid file path. file should be in the following format:
            e.g.
            [
                {
                    "config":{
                        "name":"",
                        "def":"suite_order()",
                        "request":{}
                    }
                },
                {
                    "test":{
                        "name":"add product to cart",
                        "api":"api_add_cart()",
                        "validate":[]
                    }
                },
                {
                    "test":{
                        "name":"add product to cart",
                        "suite":"create_and_check()",
                        validate":[]
                    }
                },
                {
                    "test":{
                        "name":"checkout cart",
                        "request":{},
                        "validate":[]
                    }
                }
            ]
    Returns:
        dict: testcase dict
            {
                "config":{},
                "teststeps":[teststep1,teststep2]
            }
    '''
    testcase = {"config": {}, "teststeps": []}

    for item in load_file(file_path):
        if not isinstance(item, dict) or len(item) != 1:
            raise exceptions.FileFormatError(
                f'Testcase format error: {file_path}')

        key, test_block = item.popitem()
        if not isinstance(test_block, dict):
            raise exceptions.FileFormatError(
                f'Testcase format error: {file_path}')

        if key == "config":
            testcase["config"].update(test_block)
        elif key == 'test':

            def extend_api_definition(block):
                ref_call = block["api"]
                def_block = _get_block_by_name(ref_call, 'def-api')
                _extend_block(block, def_block)

            if 'api' in test_block:
                extend_api_definition(test_block)
                testcase['teststeps'].append(test_block)
            elif 'suite' in test_block:
                ref_call = test_block['suite']
                block = _get_block_by_name(ref_call, 'def-testcase')
                for teststep in block['teststeps']:
                    if 'api' in teststep:
                        extend_api_definition(teststep)
                    testcase['teststeps'].append(teststep)
            else:
                testcase['teststeps'].append(test_block)
        else:
            logger.log_warning(
                f'unexpected block key: {key}. block key should only be "config" or "test".'
            )

    return testcase