示例#1
0
 def test_load_test_file_testcase_v2(self):
     for loaded_content in [
         loader.load_test_file("tests/testcases/setup.v2.yml"),
         loader.load_test_file("tests/testcases/setup.v2.json")
     ]:
         self.assertEqual(loaded_content["type"], "testcase")
         self.assertIn("path", loaded_content)
         self.assertIn("config", loaded_content)
         self.assertEqual(loaded_content["config"]["name"], "setup and reset all.")
         self.assertIn("teststeps", loaded_content)
         self.assertEqual(len(loaded_content["teststeps"]), 2)
示例#2
0
    def test_load_test_file_testsuite_v2(self):
        for loaded_content in [
                loader.load_test_file("tests/testsuites/create_users.v2.yml"),
                loader.load_test_file("tests/testsuites/create_users.v2.json")
        ]:
            self.assertEqual(loaded_content["type"], "testsuite")

            testcases = loaded_content["testcases"]
            self.assertEqual(len(testcases), 2)
            self.assertIn('create user 1000 and check result.', testcases)
            self.assertIn('testcase_def',
                          testcases["create user 1000 and check result."])
            self.assertEqual(
                testcases["create user 1000 and check result."]["testcase_def"]
                ["config"]["name"], "create user and check result.")
示例#3
0
 def test_create_suite(self):
     testcase_file_path = os.path.join(
         os.getcwd(), 'tests/data/demo_testset_variables.yml')
     testset = loader.load_test_file(testcase_file_path)
     suite = task.TestSuite(testset)
     self.assertEqual(suite.countTestCases(), 3)
     for testcase in suite:
         self.assertIsInstance(testcase, task.TestCase)
示例#4
0
 def test_load_test_file_testcase(self):
     loaded_content = loader.load_test_file("tests/testcases/setup.yml")
     self.assertEqual(loaded_content["type"], "testcase")
     self.assertIn("path", loaded_content)
     self.assertIn("config", loaded_content)
     self.assertEqual(loaded_content["config"]["name"],
                      "setup and reset all.")
     self.assertIn("teststeps", loaded_content)
     self.assertEqual(len(loaded_content["teststeps"]), 2)
示例#5
0
 def test_load_test_file_testcase(self):
     loader.load_test_dependencies()
     testset = loader.load_test_file("tests/testcases/smoketest.yml")
     self.assertEqual(testset["config"]["name"], "smoketest")
     self.assertEqual(testset["config"]["path"],
                      "tests/testcases/smoketest.yml")
     self.assertIn("device_sn", testset["config"]["variables"][0])
     self.assertEqual(len(testset["testcases"]), 8)
     self.assertEqual(testset["testcases"][0]["name"], "get token")
示例#6
0
def make_testsuite(testsuite: Dict) -> NoReturn:
    """convert valid testsuite dict to pytest folder with testcases"""
    # validate testsuite format
    load_testsuite(testsuite)

    testsuite_config = testsuite["config"]
    testsuite_path = testsuite_config["path"]
    testsuite_variables = convert_variables(
        testsuite_config.get("variables", {}), testsuite_path
    )

    logger.info(f"start to make testsuite: {testsuite_path}")

    # create directory with testsuite file name, put its testcases under this directory
    testsuite_path = ensure_file_abs_path_valid(testsuite_path)
    testsuite_dir, file_suffix = os.path.splitext(testsuite_path)
    # demo_testsuite.yml => demo_testsuite_yml
    testsuite_dir = f"{testsuite_dir}_{file_suffix.lstrip('.')}"

    for testcase in testsuite["testcases"]:
        # get referenced testcase content
        testcase_file = testcase["testcase"]
        logger.debug(f"[make_testsuite] testcase_file={testcase_file}")
        testcase_path = __ensure_absolute(testcase_file)
        testcase_dict = load_test_file(testcase_path)
        testcase_dict.setdefault("config", {})
        testcase_dict["config"]["path"] = testcase_path

        # override testcase name
        testcase_dict["config"]["name"] = testcase["name"]
        # override base_url
        base_url = testsuite_config.get("base_url") or testcase.get("base_url")
        if base_url:
            testcase_dict["config"]["base_url"] = base_url
        # override verify
        if "verify" in testsuite_config:
            testcase_dict["config"]["verify"] = testsuite_config["verify"]
        # override variables
        # testsuite testcase variables > testsuite config variables
        testcase_variables = convert_variables(
            testcase.get("variables", {}), testcase_path
        )
        testcase_variables = merge_variables(testcase_variables, testsuite_variables)
        # testsuite testcase variables > testcase config variables
        testcase_dict["config"]["variables"] = convert_variables(
            testcase_dict["config"].get("variables", {}), testcase_path
        )
        testcase_dict["config"]["variables"].update(testcase_variables)

        # override weight
        if "weight" in testcase:
            testcase_dict["config"]["weight"] = testcase["weight"]

        # make testcase
        testcase_pytest_path = make_testcase(testcase_dict, testsuite_dir)
        pytest_files_run_set.add(testcase_pytest_path)
示例#7
0
 def test_load_test_file_suite(self):
     loader.load_api_file("tests/api/basic.yml")
     testset = loader.load_test_file("tests/suite/create_and_get.yml")
     self.assertEqual(testset["config"]["name"],
                      "create user and check result.")
     self.assertEqual(len(testset["testcases"]), 3)
     self.assertEqual(testset["testcases"][0]["name"],
                      "make sure user $uid does not exist")
     self.assertEqual(testset["testcases"][0]["request"]["url"],
                      "/api/users/$uid")
示例#8
0
def make_testsuite(testsuite: Dict) -> List[Text]:
    """convert valid testsuite dict to pytest folder with testcases"""
    try:
        # validate testcase format
        load_testsuite(testsuite)
    except exceptions.TestSuiteFormatError as ex:
        logger.error(f"TestSuiteFormatError: {ex}")
        raise

    config = testsuite["config"]
    testsuite_path = config["path"]
    project_meta = load_project_meta(testsuite_path)
    project_working_directory = project_meta.PWD

    testsuite_variables = config.get("variables", {})
    if isinstance(testsuite_variables, Text):
        # get variables by function, e.g. ${get_variables()}
        testsuite_variables = parse_data(
            testsuite_variables, {}, project_meta.functions
        )

    logger.info(f"start to make testsuite: {testsuite_path}")

    # create directory with testsuite file name, put its testcases under this directory
    testsuite_dir = testsuite_path.replace(".", "_")
    os.makedirs(testsuite_dir, exist_ok=True)

    testcase_files = []

    for testcase in testsuite["testcases"]:
        # get referenced testcase content
        testcase_file = testcase["testcase"]
        testcase_path = os.path.join(project_working_directory, testcase_file)
        testcase_dict = load_test_file(testcase_path)
        testcase_dict.setdefault("config", {})
        testcase_dict["config"]["path"] = os.path.join(
            testsuite_dir, os.path.basename(testcase_path)
        )

        # override testcase name
        testcase_dict["config"]["name"] = testcase["name"]
        # override base_url
        base_url = testsuite["config"].get("base_url") or testcase.get("base_url")
        if base_url:
            testcase_dict["config"]["base_url"] = base_url
        # override variables
        testcase_dict["config"].setdefault("variables", {})
        testcase_dict["config"]["variables"].update(testcase.get("variables", {}))
        testcase_dict["config"]["variables"].update(testsuite_variables)

        # make testcase
        testcase_path = make_testcase(testcase_dict)
        testcase_files.append(testcase_path)

    return testcase_files
示例#9
0
def __make(tests_path: Text, ref_flag: bool = False) -> 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
        ref_flag: flag if referenced test 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_set.add(test_file)
            continue

        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, ref_flag=ref_flag)
            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}")
示例#10
0
文件: make.py 项目: tcw0nw/httprunner
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}")
示例#11
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
示例#12
0
文件: make.py 项目: tcw0nw/httprunner
def __make_testsuite(testsuite: Dict) -> NoReturn:
    """convert valid testsuite dict to pytest folder with testcases"""
    # validate testsuite format
    load_testsuite(testsuite)

    config = testsuite["config"]
    testsuite_path = config["path"]

    testsuite_variables = config.get("variables", {})
    if isinstance(testsuite_variables, Text):
        # get variables by function, e.g. ${get_variables()}
        project_meta = load_project_meta(testsuite_path)
        testsuite_variables = parse_data(testsuite_variables, {},
                                         project_meta.functions)

    logger.info(f"start to make testsuite: {testsuite_path}")

    # create directory with testsuite file name, put its testcases under this directory
    testsuite_dir = os.path.join(
        os.path.dirname(testsuite_path),
        os.path.basename(testsuite_path).replace(".", "_"),
    )
    os.makedirs(testsuite_dir, exist_ok=True)

    for testcase in testsuite["testcases"]:
        # get referenced testcase content
        testcase_file = testcase["testcase"]
        testcase_path = __ensure_absolute(testcase_file)
        testcase_dict = load_test_file(testcase_path)
        testcase_dict.setdefault("config", {})
        testcase_dict["config"]["path"] = testcase_path

        # override testcase name
        testcase_dict["config"]["name"] = testcase["name"]
        # override base_url
        base_url = testsuite["config"].get("base_url") or testcase.get(
            "base_url")
        if base_url:
            testcase_dict["config"]["base_url"] = base_url
        # override variables
        testcase_dict["config"].setdefault("variables", {})
        testcase_dict["config"]["variables"].update(
            testcase.get("variables", {}))
        testcase_dict["config"]["variables"].update(testsuite_variables)

        # make testcase
        __make_testcase(testcase_dict, testsuite_dir)
示例#13
0
def gen_locustfile(testcase_file_path):
    """ generate locustfile from template.
    """
    locustfile_path = 'locustfile.py'
    template_path = os.path.join(
        os.path.dirname(os.path.realpath(__file__)),
        "templates",
        "locustfile_template"
    )
    loader.load_test_dependencies()
    testset = loader.load_test_file(testcase_file_path)
    host = testset.get("config", {}).get("request", {}).get("base_url", "")

    with io.open(template_path, encoding='utf-8') as template:
        with io.open(locustfile_path, 'w', encoding='utf-8') as locustfile:
            template_content = template.read()
            template_content = template_content.replace("$HOST", host)
            template_content = template_content.replace("$TESTCASE_FILE", testcase_file_path)
            locustfile.write(template_content)

    return locustfile_path
示例#14
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

    """
    logger.info(f"make path: {tests_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(
                f"Invalid test file: {test_file}\n{type(ex).__name__}: {ex}")
            continue

        if not isinstance(test_content, Dict):
            logger.warning(f"Invalid test file: {test_file}\n"
                           f"reason: test content not in dict format.")
            continue

        # 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:
            logger.warning(f"Invalid testcase/testsuite file: {test_file}\n"
                           f"reason: missing config part.")
            continue
        elif not isinstance(test_content["config"], Dict):
            logger.warning(
                f"Invalid testcase/testsuite file: {test_file}\n"
                f"reason: config should be dict type, got {test_content['config']}"
            )
            continue

        # ensure path absolute
        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 as ex:
                logger.warning(
                    f"Invalid testcase file: {test_file}\n{type(ex).__name__}: {ex}"
                )
                continue

        # testsuite
        elif "testcases" in test_content:
            try:
                make_testsuite(test_content)
            except exceptions.TestSuiteFormatError as ex:
                logger.warning(
                    f"Invalid testsuite file: {test_file}\n{type(ex).__name__}: {ex}"
                )
                continue

        # invalid format
        else:
            logger.warning(
                f"Invalid test file: {test_file}\n"
                f"reason: file content is neither testcase nor testsuite")
示例#15
0
def make_testcase(testcase: Dict, dir_path: Text = None) -> Text:
    """convert valid testcase dict to pytest file path"""
    # ensure compatibility with testcase format v2
    testcase = ensure_testcase_v3(testcase)

    # validate testcase format
    load_testcase(testcase)

    testcase_abs_path = __ensure_absolute(testcase["config"]["path"])
    logger.info(f"start to make testcase: {testcase_abs_path}")

    testcase_python_abs_path, testcase_cls_name = convert_testcase_path(
        testcase_abs_path)
    if dir_path:
        testcase_python_abs_path = os.path.join(
            dir_path, os.path.basename(testcase_python_abs_path))

    global pytest_files_made_cache_mapping
    if testcase_python_abs_path in pytest_files_made_cache_mapping:
        return testcase_python_abs_path

    config = testcase["config"]
    config["path"] = convert_relative_project_root_dir(
        testcase_python_abs_path)
    config["variables"] = convert_variables(config.get("variables", {}),
                                            testcase_abs_path)

    # prepare reference testcase
    imports_list = []
    teststeps = testcase["teststeps"]
    for teststep in teststeps:
        if not teststep.get("testcase"):
            continue

        # make ref testcase pytest file
        ref_testcase_path = __ensure_absolute(teststep["testcase"])
        test_content = load_test_file(ref_testcase_path)

        # 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)

        test_content.setdefault("config", {})["path"] = ref_testcase_path
        ref_testcase_python_abs_path = make_testcase(test_content)

        # override testcase export
        ref_testcase_export: List = test_content["config"].get("export", [])
        if ref_testcase_export:
            step_export: List = teststep.setdefault("export", [])
            step_export.extend(ref_testcase_export)
            teststep["export"] = list(set(step_export))

        # prepare ref testcase class name
        ref_testcase_cls_name = pytest_files_made_cache_mapping[
            ref_testcase_python_abs_path]
        teststep["testcase"] = ref_testcase_cls_name

        # prepare import ref testcase
        ref_testcase_python_relative_path = convert_relative_project_root_dir(
            ref_testcase_python_abs_path)
        ref_module_name, _ = os.path.splitext(
            ref_testcase_python_relative_path)
        ref_module_name = ref_module_name.replace(os.sep, ".")
        import_expr = f"from {ref_module_name} import TestCase{ref_testcase_cls_name} as {ref_testcase_cls_name}"
        if import_expr not in imports_list:
            imports_list.append(import_expr)

    testcase_path = convert_relative_project_root_dir(testcase_abs_path)
    # current file compared to ProjectRootDir
    diff_levels = len(testcase_path.split(os.sep))

    data = {
        "version":
        __version__,
        "testcase_path":
        testcase_path,
        "diff_levels":
        diff_levels,
        "class_name":
        f"TestCase{testcase_cls_name}",
        "imports_list":
        imports_list,
        "config_chain_style":
        make_config_chain_style(config),
        "customization_test_start":
        make_test_start_style(config),
        "teststeps_chain_style":
        [make_teststep_chain_style(step) for step in teststeps],
    }
    content = __TEMPLATE__.render(data)

    # ensure new file's directory exists
    dir_path = os.path.dirname(testcase_python_abs_path)
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)

    with open(testcase_python_abs_path, "w", encoding="utf-8") as f:
        f.write(content)

    pytest_files_made_cache_mapping[
        testcase_python_abs_path] = testcase_cls_name
    __ensure_testcase_module(testcase_python_abs_path)

    logger.info(f"generated testcase: {testcase_python_abs_path}")

    return testcase_python_abs_path
示例#16
0
 def test_load_test_file_api(self):
     loaded_content = loader.load_test_file("tests/api/create_user.yml")
     self.assertEqual(loaded_content["type"], "api")
     self.assertIn("path", loaded_content)
     self.assertIn("request", loaded_content)
     self.assertEqual(loaded_content["request"]["url"], "/api/users/$uid")
示例#17
0
def make_testcase(testcase: Dict, dir_path: Text = None) -> Text:
    """convert valid testcase dict to pytest file path"""
    # ensure compatibility with testcase format v2
    testcase = ensure_testcase_v3(testcase)

    # validate testcase format
    load_testcase(testcase)

    testcase_abs_path = __ensure_absolute(testcase["config"]["path"])
    logger.info(f"start to make testcase: {testcase_abs_path}")

    testcase_python_path, testcase_cls_name = convert_testcase_path(
        testcase_abs_path)
    if dir_path:
        testcase_python_path = os.path.join(
            dir_path, os.path.basename(testcase_python_path))

    global pytest_files_made_cache_mapping
    if testcase_python_path in pytest_files_made_cache_mapping:
        return testcase_python_path

    config = testcase["config"]
    config["path"] = __ensure_cwd_relative(testcase_python_path)
    config["variables"] = convert_variables(config.get("variables", {}),
                                            testcase_abs_path)

    # prepare reference testcase
    imports_list = []
    teststeps = testcase["teststeps"]
    for teststep in teststeps:
        if not teststep.get("testcase"):
            continue

        # make ref testcase pytest file
        ref_testcase_path = __ensure_absolute(teststep["testcase"])
        test_content = load_test_file(ref_testcase_path)
        test_content.setdefault("config", {})["path"] = ref_testcase_path
        ref_testcase_python_path = make_testcase(test_content)

        # prepare ref testcase class name
        ref_testcase_cls_name = pytest_files_made_cache_mapping[
            ref_testcase_python_path]
        teststep["testcase"] = ref_testcase_cls_name

        # prepare import ref testcase
        ref_testcase_python_path = ref_testcase_python_path[len(os.getcwd()) +
                                                            1:]
        ref_module_name, _ = os.path.splitext(ref_testcase_python_path)
        ref_module_name = ref_module_name.replace(os.sep, ".")
        imports_list.append(
            f"from {ref_module_name} import TestCase{ref_testcase_cls_name} as {ref_testcase_cls_name}"
        )

    data = {
        "version":
        __version__,
        "testcase_path":
        __ensure_cwd_relative(testcase_abs_path),
        "class_name":
        f"TestCase{testcase_cls_name}",
        "imports_list":
        imports_list,
        "config_chain_style":
        make_config_chain_style(config),
        "teststeps_chain_style":
        [make_teststep_chain_style(step) for step in teststeps],
    }
    content = __TEMPLATE__.render(data)

    # ensure new file's directory exists
    dir_path = os.path.dirname(testcase_python_path)
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)

    with open(testcase_python_path, "w", encoding="utf-8") as f:
        f.write(content)

    pytest_files_made_cache_mapping[testcase_python_path] = testcase_cls_name
    __ensure_testcase_module(testcase_python_path)

    logger.info(f"generated testcase: {testcase_python_path}")

    return testcase_python_path