示例#1
0
class VariableBindsUnittest(unittest.TestCase):
    def setUp(self):
        self.context = Context()
        testcase_file_path = os.path.join(os.getcwd(),
                                          'tests/data/demo_binds.yml')
        self.testcases = utils.load_testcases(testcase_file_path)

    def test_context_bind_testset_variables(self):
        # testcase in JSON format
        testcase1 = {
            "variable_binds": [{
                "GLOBAL_TOKEN": "debugtalk"
            }, {
                "token": "$GLOBAL_TOKEN"
            }]
        }
        # testcase in YAML format
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds, level="testset")

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.get_testcase_variables_mapping()
            self.assertIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testset_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testset_variables["token"], "debugtalk")

    def test_context_bind_testcase_variables(self):
        testcase1 = {
            "variable_binds": [{
                "GLOBAL_TOKEN": "debugtalk"
            }, {
                "token": "$GLOBAL_TOKEN"
            }]
        }
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.get_testcase_variables_mapping()
            self.assertNotIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testcase_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertNotIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testcase_variables["token"], "debugtalk")

    def test_context_bind_lambda_functions(self):
        testcase1 = {
            "function_binds": {
                "add_one": lambda x: x + 1,
                "add_two_nums": lambda x, y: x + y
            },
            "variable_binds": [{
                "add1": "${add_one(2)}"
            }, {
                "sum2nums": "${add_two_nums(2,3)}"
            }]
        }
        testcase2 = self.testcases["bind_lambda_functions"]

        for testcase in [testcase1, testcase2]:
            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            context_variables = self.context.get_testcase_variables_mapping()
            self.assertIn("add1", context_variables)
            self.assertEqual(context_variables["add1"], 3)
            self.assertIn("sum2nums", context_variables)
            self.assertEqual(context_variables["sum2nums"], 5)

    def test_context_bind_lambda_functions_with_import(self):
        testcase1 = {
            "requires": ["random", "string", "hashlib"],
            "function_binds": {
                "gen_random_string":
                "lambda str_len: ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(str_len))",
                "gen_md5":
                "lambda *str_args: hashlib.md5(''.join(str_args).encode('utf-8')).hexdigest()"
            },
            "variable_binds": [{
                "TOKEN": "debugtalk"
            }, {
                "random": "${gen_random_string(5)}"
            }, {
                "data": '{"name": "user", "password": "******"}'
            }, {
                "authorization":
                "${gen_md5($TOKEN, $data, $random)}"
            }]
        }
        testcase2 = self.testcases["bind_lambda_functions_with_import"]

        for testcase in [testcase1, testcase2]:
            requires = testcase.get('requires', [])
            self.context.import_requires(requires)

            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)
            context_variables = self.context.get_testcase_variables_mapping()

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(utils.gen_md5(TOKEN, data, random), authorization)

    def test_import_module_functions(self):
        testcase1 = {
            "import_module_functions": ["tests.data.custom_functions"],
            "variable_binds": [{
                "TOKEN": "debugtalk"
            }, {
                "random": "${gen_random_string(5)}"
            }, {
                "data": '{"name": "user", "password": "******"}'
            }, {
                "authorization":
                "${gen_md5($TOKEN, $data, $random)}"
            }]
        }
        testcase2 = self.testcases["bind_module_functions"]

        for testcase in [testcase1, testcase2]:
            module_functions = testcase.get('import_module_functions', [])
            self.context.import_module_functions(module_functions)

            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)
            context_variables = self.context.get_testcase_variables_mapping()

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(utils.gen_md5(TOKEN, data, random), authorization)

    def test_get_parsed_request(self):
        test_runner = runner.Runner()
        testcase = {
            "import_module_functions": ["tests.data.custom_functions"],
            "variable_binds": [{
                "TOKEN": "debugtalk"
            }, {
                "random": "${gen_random_string(5)}"
            }, {
                "data": '{"name": "user", "password": "******"}'
            }, {
                "authorization":
                "${gen_md5($TOKEN, $data, $random)}"
            }],
            "request": {
                "url": "http://127.0.0.1:5000/api/users/1000",
                "method": "POST",
                "headers": {
                    "Content-Type": "application/json",
                    "authorization": "$authorization",
                    "random": "$random"
                },
                "data": "$data"
            }
        }
        test_runner.init_config(testcase, level="testcase")
        parsed_request = test_runner.context.get_parsed_request()
        self.assertIn("authorization", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["authorization"]), 32)
        self.assertIn("random", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["random"]), 5)
        self.assertIn("data", parsed_request)
        self.assertEqual(parsed_request["data"],
                         testcase["variable_binds"][2]["data"])
示例#2
0
class Runner(object):
    def __init__(self, http_client_session=None):
        self.http_client_session = http_client_session
        self.context = Context()

    def init_config(self, config_dict, level):
        """ create/update context variables binds
        @param (dict) config_dict
            {
                "name": "description content",
                "requires": ["random", "hashlib"],
                "function_binds": {
                    "gen_random_string": \
                        "lambda str_len: ''.join(random.choice(string.ascii_letters + \
                        string.digits) for _ in range(str_len))",
                    "gen_md5": \
                        "lambda *str_args: hashlib.md5(''.join(str_args).\
                        encode('utf-8')).hexdigest()"
                },
                "import_module_functions": ["test.data.custom_functions"],
                "variable_binds": [
                    {"TOKEN": "debugtalk"},
                    {"random": "${gen_random_string(5)}"},
                ]
            }
        @param (str) context level, testcase or testset
        """
        self.context.init_context(level)

        requires = config_dict.get('requires', [])
        self.context.import_requires(requires)

        function_binds = config_dict.get('function_binds', {})
        self.context.bind_functions(function_binds, level)

        module_functions = config_dict.get('import_module_functions', [])
        self.context.import_module_functions(module_functions, level)

        variable_binds = config_dict.get('variable_binds', [])
        self.context.bind_variables(variable_binds, level)

        request_config = config_dict.get('request', {})
        if level == "testset":
            base_url = request_config.pop("base_url", None)
            self.http_client_session = self.http_client_session or HttpSession(
                base_url)
        else:
            # testcase
            self.http_client_session = self.http_client_session or requests.Session(
            )
        self.context.register_request(request_config, level)

    def run_test(self, testcase):
        """ run single testcase.
        @param (dict) testcase
            {
                "name": "testcase description",
                "times": 3,
                "requires": [],  # optional, override
                "function_binds": {}, # optional, override
                "variable_binds": {}, # optional, override
                "request": {
                    "url": "http://127.0.0.1:5000/api/users/1000",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "authorization": "$authorization",
                        "random": "$random"
                    },
                    "body": '{"name": "user", "password": "******"}'
                },
                "extract_binds": {}, # optional
                "validators": []     # optional
            }
        @return True or raise exception during test
        """
        self.init_config(testcase, level="testcase")
        parsed_request = self.context.get_parsed_request()

        try:
            url = parsed_request.pop('url')
            method = parsed_request.pop('method')
        except KeyError:
            raise exception.ParamsError("URL or METHOD missed!")

        run_times = int(testcase.get("times", 1))
        extract_binds = testcase.get("extract_binds", {})
        validators = testcase.get("validators", [])

        for _ in range(run_times):
            resp = self.http_client_session.request(url=url,
                                                    method=method,
                                                    **parsed_request)
            resp_obj = response.ResponseObject(resp)

            extracted_variables_mapping_list = resp_obj.extract_response(
                extract_binds)
            self.context.bind_variables(extracted_variables_mapping_list,
                                        level="testset")

            resp_obj.validate(validators,
                              self.context.get_testcase_variables_mapping())

        return True

    def run_testset(self, testset):
        """ run single testset, including one or several testcases.
        @param (dict) testset
            {
                "name": "testset description",
                "config": {
                    "name": "testset description",
                    "requires": [],
                    "function_binds": {},
                    "variable_binds": [],
                    "request": {}
                },
                "testcases": [
                    {
                        "name": "testcase description",
                        "variable_binds": {}, # optional, override
                        "request": {},
                        "extract_binds": {},  # optional
                        "validators": {}      # optional
                    },
                    testcase12
                ]
            }
        @return (list) test results of testcases
            [
                (success, diff_content),    # testcase1
                (success, diff_content)     # testcase2
            ]
        """
        results = []

        config_dict = testset.get("config", {})
        self.init_config(config_dict, level="testset")
        testcases = testset.get("testcases", [])
        for testcase in testcases:
            result = self.run_test(testcase)
            results.append(result)

        return results

    def run_testsets(self, testsets):
        """ run testsets, including one or several testsets.
        @param testsets
            [
                testset1,
                testset2,
            ]
        @return (list) test results of testsets
            [
                [   # testset1
                    (success, diff_content),    # testcase11
                    (success, diff_content)     # testcase12
                ],
                [   # testset2
                    (success, diff_content),    # testcase21
                    (success, diff_content)     # testcase22
                ]
            ]
        """
        return [self.run_testset(testset) for testset in testsets]
示例#3
0
class VariableBindsUnittest(unittest.TestCase):

    def setUp(self):
        self.context = Context()
        testcase_file_path = os.path.join(os.getcwd(), 'tests/data/demo_binds.yml')
        self.testcases = utils.load_testcases(testcase_file_path)

    def test_context_init_functions(self):
        self.assertIn("get_timestamp", self.context.testset_functions_config)
        self.assertIn("gen_random_string", self.context.testset_functions_config)

        variable_binds = [
            {"random": "${gen_random_string(5)}"},
            {"timestamp10": "${get_timestamp(10)}"}
        ]
        self.context.bind_variables(variable_binds)
        context_variables = self.context.get_testcase_variables_mapping()

        self.assertEqual(len(context_variables["random"]), 5)
        self.assertEqual(len(context_variables["timestamp10"]), 10)

    def test_context_bind_testset_variables(self):
        # testcase in JSON format
        testcase1 = {
            "variable_binds": [
                {"GLOBAL_TOKEN": "debugtalk"},
                {"token": "$GLOBAL_TOKEN"}
            ]
        }
        # testcase in YAML format
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds, level="testset")

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.get_testcase_variables_mapping()
            self.assertIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testset_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testset_variables["token"], "debugtalk")

    def test_context_bind_testcase_variables(self):
        testcase1 = {
            "variable_binds": [
                {"GLOBAL_TOKEN": "debugtalk"},
                {"token": "$GLOBAL_TOKEN"}
            ]
        }
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.get_testcase_variables_mapping()
            self.assertNotIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testcase_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertNotIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testcase_variables["token"], "debugtalk")

    def test_context_bind_lambda_functions(self):
        testcase1 = {
            "function_binds": {
                "add_one": lambda x: x + 1,
                "add_two_nums": lambda x, y: x + y
            },
            "variable_binds": [
                {"add1": "${add_one(2)}"},
                {"sum2nums": "${add_two_nums(2,3)}"}
            ]
        }
        testcase2 = self.testcases["bind_lambda_functions"]

        for testcase in [testcase1, testcase2]:
            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            context_variables = self.context.get_testcase_variables_mapping()
            self.assertIn("add1", context_variables)
            self.assertEqual(context_variables["add1"], 3)
            self.assertIn("sum2nums", context_variables)
            self.assertEqual(context_variables["sum2nums"], 5)

    def test_context_bind_lambda_functions_with_import(self):
        testcase1 = {
            "requires": ["random", "string", "hashlib"],
            "function_binds": {
                "gen_random_string": "lambda str_len: ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(str_len))",
                "gen_md5": "lambda *str_args: hashlib.md5(''.join(str_args).encode('utf-8')).hexdigest()"
            },
            "variable_binds": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ]
        }
        testcase2 = self.testcases["bind_lambda_functions_with_import"]

        for testcase in [testcase1, testcase2]:
            requires = testcase.get('requires', [])
            self.context.import_requires(requires)

            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)
            context_variables = self.context.get_testcase_variables_mapping()

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(utils.gen_md5(TOKEN, data, random), authorization)

    def test_import_module_items(self):
        testcase1 = {
            "import_module_items": ["tests.data.debugtalk"],
            "variable_binds": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ]
        }
        testcase2 = self.testcases["bind_module_functions"]

        for testcase in [testcase1, testcase2]:
            module_items = testcase.get('import_module_items', [])
            self.context.import_module_items(module_items)

            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)
            context_variables = self.context.get_testcase_variables_mapping()

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(utils.gen_md5(TOKEN, data, random), authorization)
            self.assertIn("SECRET_KEY", context_variables)
            SECRET_KEY = context_variables["SECRET_KEY"]
            self.assertEqual(SECRET_KEY, "DebugTalk")

    def test_register_request(self):
        request_dict = {
            "url": "http://debugtalk.com",
            "method": "GET",
            "headers": {
                "Content-Type": "application/json",
                "USER-AGENT": "ios/10.3"
            }
        }
        self.context.register_request(request_dict)

        parsed_request = self.context.get_parsed_request()
        self.assertIn("content-type", parsed_request["headers"])
        self.assertIn("user-agent", parsed_request["headers"])

        request_dict = {
            "headers": "invalid headers"
        }
        with self.assertRaises(ParamsError):
            self.context.register_request(request_dict)

    def test_get_parsed_request(self):
        test_runner = runner.Runner()
        testcase = {
            "import_module_items": ["tests.data.debugtalk"],
            "variable_binds": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ],
            "request": {
                "url": "http://127.0.0.1:5000/api/users/1000",
                "method": "POST",
                "headers": {
                    "Content-Type": "application/json",
                    "authorization": "$authorization",
                    "random": "$random",
                    "SECRET_KEY": "$SECRET_KEY"
                },
                "data": "$data"
            }
        }
        test_runner.init_config(testcase, level="testcase")
        parsed_request = test_runner.context.get_parsed_request()
        self.assertIn("authorization", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["authorization"]), 32)
        self.assertIn("random", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["random"]), 5)
        self.assertIn("data", parsed_request)
        self.assertEqual(parsed_request["data"], testcase["variable_binds"][2]["data"])
        self.assertEqual(parsed_request["headers"]["secret_key"], "DebugTalk")

    def test_exec_content_functions(self):
        test_runner = runner.Runner()
        content = "${sleep(1)}"
        start_time = time.time()
        test_runner.context.exec_content_functions(content)
        end_time = time.time()
        elapsed_time = end_time - start_time
        self.assertGreater(elapsed_time, 1)
示例#4
0
class VariableBindsUnittest(unittest.TestCase):
    def setUp(self):
        self.context = Context()
        testcase_file_path = os.path.join(os.getcwd(),
                                          'test/data/demo_binds.yml')
        self.testcases = utils.load_testcases(testcase_file_path)

    def test_context_variable_string(self):
        # testcase in JSON format
        testcase1 = {"variable_binds": [{"TOKEN": "debugtalk"}]}
        # testcase in YAML format
        testcase2 = self.testcases[0]

        for testcase in [testcase1, testcase2]:
            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            context_variables = self.context.variables
            self.assertIn("TOKEN", context_variables)
            self.assertEqual(context_variables["TOKEN"], "debugtalk")

    def test_context_variable_list(self):
        testcase1 = {"variable_binds": [{"var": [1, 2, 3]}]}
        testcase2 = self.testcases[1]

        for testcase in [testcase1, testcase2]:
            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            context_variables = self.context.variables
            self.assertIn("var", context_variables)
            self.assertEqual(context_variables["var"], [1, 2, 3])

    def test_context_variable_json(self):
        testcase1 = {
            "variable_binds": [{
                "data": {
                    'name': 'user',
                    'password': '******'
                }
            }]
        }
        testcase2 = self.testcases[2]

        for testcase in [testcase1, testcase2]:
            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            context_variables = self.context.variables
            self.assertIn("data", context_variables)
            self.assertEqual(context_variables["data"], {
                'name': 'user',
                'password': '******'
            })

    def test_context_variable_variable(self):
        testcase1 = {
            "variable_binds": [{
                "GLOBAL_TOKEN": "debugtalk"
            }, {
                "token": "${GLOBAL_TOKEN}"
            }]
        }
        testcase2 = self.testcases[3]

        for testcase in [testcase1, testcase2]:
            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            context_variables = self.context.variables
            self.assertIn("GLOBAL_TOKEN", context_variables)
            self.assertEqual(context_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertIn("token", context_variables)
            self.assertEqual(context_variables["token"], "debugtalk")

    def test_context_variable_function_lambda(self):
        testcase1 = {
            "function_binds": {
                "add_one": lambda x: x + 1,
                "add_two_nums": lambda x, y: x + y
            },
            "variable_binds": [{
                "add1": {
                    "func": "add_one",
                    "args": [2]
                }
            }, {
                "sum2nums": {
                    "func": "add_two_nums",
                    "args": [2, 3]
                }
            }]
        }
        testcase2 = self.testcases[4]

        for testcase in [testcase1, testcase2]:
            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            context_variables = self.context.variables
            self.assertIn("add1", context_variables)
            self.assertEqual(context_variables["add1"], 3)
            self.assertIn("sum2nums", context_variables)
            self.assertEqual(context_variables["sum2nums"], 5)

    def test_context_variable_function_lambda_with_import(self):
        testcase1 = {
            "requires": ["random", "string", "hashlib"],
            "function_binds": {
                "gen_random_string":
                "lambda str_len: ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(str_len))",
                "gen_md5":
                "lambda *str_args: hashlib.md5(''.join(str_args).encode('utf-8')).hexdigest()"
            },
            "variable_binds": [{
                "TOKEN": "debugtalk"
            }, {
                "random": {
                    "func": "gen_random_string",
                    "args": [5]
                }
            }, {
                "data": "{'name': 'user', 'password': '******'}"
            }, {
                "md5": {
                    "func": "gen_md5",
                    "args": ["$TOKEN", "$data", "$random"]
                }
            }]
        }
        testcase2 = self.testcases[5]

        for testcase in [testcase1, testcase2]:
            requires = testcase.get('requires', [])
            self.context.import_requires(requires)

            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            context_variables = self.context.variables
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            self.assertIn("md5", context_variables)
            self.assertEqual(len(context_variables["md5"]), 32)
示例#5
0
class TestRunner(object):
    def __init__(self):
        self.client = requests.Session()
        self.context = Context()

    def update_context(self, config_dict):
        """ create/update context variables binds
        @param config_dict
            {
                "name": "description content",
                "requires": ["random", "hashlib"],
                "function_binds": {
                    "gen_random_string": \
                        "lambda str_len: ''.join(random.choice(string.ascii_letters + \
                        string.digits) for _ in range(str_len))",
                    "gen_md5": \
                        "lambda *str_args: hashlib.md5(''.join(str_args).\
                        encode('utf-8')).hexdigest()"
                },
                "variable_binds": [
                    {"TOKEN": "debugtalk"},
                    {"random": {"func": "gen_random_string", "args": [5]}},
                ]
            }
        """
        requires = config_dict.get('requires', [])
        self.context.import_requires(requires)

        function_binds = config_dict.get('function_binds', {})
        self.context.bind_functions(function_binds)

        variable_binds = config_dict.get('variable_binds', [])
        self.context.bind_variables(variable_binds)

    def run_test(self, testcase):
        """ run single testcase.
        @param (dict) testcase
            {
                "name": "testcase description",
                "requires": [],  # optional, override
                "function_binds": {}, # optional, override
                "variable_binds": {}, # optional, override
                "request": {
                    "url": "http://127.0.0.1:5000/api/users/1000",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "authorization": "${authorization}",
                        "random": "${random}"
                    },
                    "body": '{"name": "user", "password": "******"}'
                },
                "extract_binds": {},
                "validators": {}
            }
        @return (tuple) test result of single testcase
            (success, diff_content)
        """
        self.update_context(testcase)
        parsed_request = parse_template(testcase["request"],
                                        self.context.variables)

        try:
            url = parsed_request.pop('url')
            method = parsed_request.pop('method')
        except KeyError:
            raise exception.ParamsError("URL or METHOD missed!")

        resp = self.client.request(url=url, method=method, **parsed_request)
        resp_obj = response.ResponseObject(resp)

        extract_binds = testcase.get("extract_binds", {})
        extract_binds_dict = resp_obj.extract_response(extract_binds)
        self.context.update_variables(extract_binds_dict)

        validators = testcase.get("validators", {})
        diff_content_dict = resp_obj.validate(validators,
                                              self.context.variables)

        return resp_obj.success, diff_content_dict

    def run_testset(self, testset):
        """ run single testset, including one or several testcases.
        @param (dict) testset
            {
                "name": "testset description",
                "config": {
                    "name": "testset description",
                    "requires": [],
                    "function_binds": {},
                    "variable_binds": []
                },
                "testcases": [
                    {
                        "name": "testcase description",
                        "variable_binds": {}, # override
                        "request": {},
                        "extract_binds": {},
                        "validators": {}
                    },
                    testcase12
                ]
            }
        @return (list) test results of testcases
            [
                (success, diff_content),    # testcase1
                (success, diff_content)     # testcase2
            ]
        """
        results = []

        config_dict = testset.get("config", {})
        self.update_context(config_dict)
        testcases = testset.get("testcases", [])
        for testcase in testcases:
            result = self.run_test(testcase)
            results.append(result)

        return results

    def run_testsets(self, testsets):
        """ run testsets, including one or several testsets.
        @param testsets
            [
                testset1,
                testset2,
            ]
        @return (list) test results of testsets
            [
                [   # testset1
                    (success, diff_content),    # testcase11
                    (success, diff_content)     # testcase12
                ],
                [   # testset2
                    (success, diff_content),    # testcase21
                    (success, diff_content)     # testcase22
                ]
            ]
        """
        return [self.run_testset(testset) for testset in testsets]
示例#6
0
class VariableBindsUnittest(unittest.TestCase):

    def setUp(self):
        self.context = Context()
        testcase_file_path = os.path.join(os.getcwd(), 'tests/data/demo_binds.yml')
        self.testcases = utils.load_testcases(testcase_file_path)

    def test_context_bind_testset_variables(self):
        # testcase in JSON format
        testcase1 = {
            "variable_binds": [
                {"GLOBAL_TOKEN": "debugtalk"},
                {"token": "$GLOBAL_TOKEN"}
            ]
        }
        # testcase in YAML format
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds, level="testset")

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.get_testcase_variables_mapping()
            self.assertIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testset_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testset_variables["token"], "debugtalk")

    def test_context_bind_testcase_variables(self):
        testcase1 = {
            "variable_binds": [
                {"GLOBAL_TOKEN": "debugtalk"},
                {"token": "$GLOBAL_TOKEN"}
            ]
        }
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.get_testcase_variables_mapping()
            self.assertNotIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testcase_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertNotIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testcase_variables["token"], "debugtalk")

    def test_context_bind_lambda_functions(self):
        testcase1 = {
            "function_binds": {
                "add_one": lambda x: x + 1,
                "add_two_nums": lambda x, y: x + y
            },
            "variable_binds": [
                {"add1": "${add_one(2)}"},
                {"sum2nums": "${add_two_nums(2,3)}"}
            ]
        }
        testcase2 = self.testcases["bind_lambda_functions"]

        for testcase in [testcase1, testcase2]:
            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)

            context_variables = self.context.get_testcase_variables_mapping()
            self.assertIn("add1", context_variables)
            self.assertEqual(context_variables["add1"], 3)
            self.assertIn("sum2nums", context_variables)
            self.assertEqual(context_variables["sum2nums"], 5)

    def test_context_bind_lambda_functions_with_import(self):
        testcase1 = {
            "requires": ["random", "string", "hashlib"],
            "function_binds": {
                "gen_random_string": "lambda str_len: ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(str_len))",
                "gen_md5": "lambda *str_args: hashlib.md5(''.join(str_args).encode('utf-8')).hexdigest()"
            },
            "variable_binds": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ]
        }
        testcase2 = self.testcases["bind_lambda_functions_with_import"]

        for testcase in [testcase1, testcase2]:
            requires = testcase.get('requires', [])
            self.context.import_requires(requires)

            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)
            context_variables = self.context.get_testcase_variables_mapping()

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(utils.gen_md5(TOKEN, data, random), authorization)

    def test_import_module_functions(self):
        testcase1 = {
            "import_module_functions": ["tests.data.custom_functions"],
            "variable_binds": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ]
        }
        testcase2 = self.testcases["bind_module_functions"]

        for testcase in [testcase1, testcase2]:
            module_functions = testcase.get('import_module_functions', [])
            self.context.import_module_functions(module_functions)

            variable_binds = testcase['variable_binds']
            self.context.bind_variables(variable_binds)
            context_variables = self.context.get_testcase_variables_mapping()

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(utils.gen_md5(TOKEN, data, random), authorization)

    def test_get_parsed_request(self):
        test_runner = runner.Runner()
        testcase = {
            "import_module_functions": ["tests.data.custom_functions"],
            "variable_binds": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ],
            "request": {
                "url": "http://127.0.0.1:5000/api/users/1000",
                "method": "POST",
                "headers": {
                    "Content-Type": "application/json",
                    "authorization": "$authorization",
                    "random": "$random"
                },
                "data": "$data"
            }
        }
        test_runner.init_config(testcase, level="testcase")
        parsed_request = test_runner.context.get_parsed_request()
        self.assertIn("authorization", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["authorization"]), 32)
        self.assertIn("random", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["random"]), 5)
        self.assertIn("data", parsed_request)
        self.assertEqual(parsed_request["data"], testcase["variable_binds"][2]["data"])
示例#7
0
class Runner(object):

    def __init__(self, http_client_session=None):
        self.http_client_session = http_client_session
        self.context = Context()

    def init_config(self, config_dict, level):
        """ create/update context variables binds
        @param (dict) config_dict
            {
                "name": "description content",
                "requires": ["random", "hashlib"],
                "function_binds": {
                    "gen_random_string": \
                        "lambda str_len: ''.join(random.choice(string.ascii_letters + \
                        string.digits) for _ in range(str_len))",
                    "gen_md5": \
                        "lambda *str_args: hashlib.md5(''.join(str_args).\
                        encode('utf-8')).hexdigest()"
                },
                "import_module_functions": ["test.data.custom_functions"],
                "variable_binds": [
                    {"TOKEN": "debugtalk"},
                    {"random": "${gen_random_string(5)}"},
                ]
            }
        @param (str) context level, testcase or testset
        """
        self.context.init_context(level)

        requires = config_dict.get('requires', [])
        self.context.import_requires(requires)

        function_binds = config_dict.get('function_binds', {})
        self.context.bind_functions(function_binds, level)

        module_functions = config_dict.get('import_module_functions', [])
        self.context.import_module_functions(module_functions, level)

        variable_binds = config_dict.get('variable_binds', [])
        self.context.bind_variables(variable_binds, level)

        request_config = config_dict.get('request', {})
        if level == "testset":
            base_url = request_config.pop("base_url", None)
            self.http_client_session = self.http_client_session or HttpSession(base_url)
        else:
            # testcase
            self.http_client_session = self.http_client_session or requests.Session()
        self.context.register_request(request_config, level)

    def run_test(self, testcase):
        """ run single testcase.
        @param (dict) testcase
            {
                "name": "testcase description",
                "times": 3,
                "requires": [],  # optional, override
                "function_binds": {}, # optional, override
                "variable_binds": {}, # optional, override
                "request": {
                    "url": "http://127.0.0.1:5000/api/users/1000",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "authorization": "$authorization",
                        "random": "$random"
                    },
                    "body": '{"name": "user", "password": "******"}'
                },
                "extract_binds": {}, # optional
                "validators": []     # optional
            }
        @return (tuple) test result of single testcase
            (success, diff_content_list)
        """
        self.init_config(testcase, level="testcase")
        parsed_request = self.context.get_parsed_request()

        try:
            url = parsed_request.pop('url')
            method = parsed_request.pop('method')
        except KeyError:
            raise exception.ParamsError("URL or METHOD missed!")

        run_times = int(testcase.get("times", 1))
        extract_binds = testcase.get("extract_binds", {})
        validators = testcase.get("validators", [])

        for _ in range(run_times):
            resp = self.http_client_session.request(url=url, method=method, **parsed_request)
            resp_obj = response.ResponseObject(resp)

            extracted_variables_mapping_list = resp_obj.extract_response(extract_binds)
            self.context.bind_variables(extracted_variables_mapping_list, level="testset")

            resp_obj.validate(validators, self.context.get_testcase_variables_mapping())

        return True

    def run_testset(self, testset):
        """ run single testset, including one or several testcases.
        @param (dict) testset
            {
                "name": "testset description",
                "config": {
                    "name": "testset description",
                    "requires": [],
                    "function_binds": {},
                    "variable_binds": [],
                    "request": {}
                },
                "testcases": [
                    {
                        "name": "testcase description",
                        "variable_binds": {}, # optional, override
                        "request": {},
                        "extract_binds": {},  # optional
                        "validators": {}      # optional
                    },
                    testcase12
                ]
            }
        @return (list) test results of testcases
            [
                (success, diff_content),    # testcase1
                (success, diff_content)     # testcase2
            ]
        """
        results = []

        config_dict = testset.get("config", {})
        self.init_config(config_dict, level="testset")
        testcases = testset.get("testcases", [])
        for testcase in testcases:
            result = self.run_test(testcase)
            results.append(result)

        return results

    def run_testsets(self, testsets):
        """ run testsets, including one or several testsets.
        @param testsets
            [
                testset1,
                testset2,
            ]
        @return (list) test results of testsets
            [
                [   # testset1
                    (success, diff_content),    # testcase11
                    (success, diff_content)     # testcase12
                ],
                [   # testset2
                    (success, diff_content),    # testcase21
                    (success, diff_content)     # testcase22
                ]
            ]
        """
        return [self.run_testset(testset) for testset in testsets]
示例#8
0
class TestRunner(object):
    def __init__(self):
        self.client = requests.Session()
        self.context = Context()
        self.testcase_parser = TestcaseParser()

    def pre_config(self, config_dict):
        """ create/update variables binds
        @param config_dict
            {
                "name": "description content",
                "requires": ["random", "hashlib"],
                "function_binds": {
                    "gen_random_string": \
                        "lambda str_len: ''.join(random.choice(string.ascii_letters + \
                        string.digits) for _ in range(str_len))",
                    "gen_md5": \
                        "lambda *str_args: hashlib.md5(''.join(str_args).\
                        encode('utf-8')).hexdigest()"
                },
                "variable_binds": [
                    {"TOKEN": "debugtalk"},
                    {"random": {"func": "gen_random_string", "args": [5]}},
                ]
            }
        """
        requires = config_dict.get('requires', [])
        self.context.import_requires(requires)

        function_binds = config_dict.get('function_binds', {})
        self.context.bind_functions(function_binds)

        variable_binds = config_dict.get('variable_binds', [])
        self.context.bind_variables(variable_binds)

        extract_binds = config_dict.get('extract_binds', {})
        self.context.bind_extractors(extract_binds)

        self.testcase_parser.update_variables_binds(self.context.variables)

    def parse_testcase(self, testcase):
        """ parse testcase with variables binds if it is a template.
        @param (dict) testcase
            {
                "name": "testcase description",
                "requires": [],  # optional, override
                "function_binds": {}, # optional, override
                "variable_binds": {}, # optional, override
                "request": {},
                "response": {}
            }
        @return (dict) parsed testcase with bind values
            {
                "request": {
                    "url": "http://127.0.0.1:5000/api/users/1000",
                    "method": "POST",
                    "headers": {
                        "Content-Type": "application/json",
                        "authorization": "a83de0ff8d2e896dbd8efb81ba14e17d",
                        "random": "A2dEx"
                    },
                    "body": '{"name": "user", "password": "******"}'
                },
                "response": {
                    "status_code": 201
                }
            }
        """
        self.pre_config(testcase)

        parsed_testcase = self.testcase_parser.parse(testcase)
        return parsed_testcase

    def run_test(self, testcase):
        """ run single testcase.
        @param (dict) testcase
            {
                "name": "testcase description",
                "requires": [],  # optional, override
                "function_binds": {}, # optional, override
                "variable_binds": {}, # optional, override
                "request": {},
                "response": {}
            }
        @return (tuple) test result of single testcase
            (success, diff_content)
        """
        testcase = self.parse_testcase(testcase)

        req_kwargs = testcase['request']

        try:
            url = req_kwargs.pop('url')
            method = req_kwargs.pop('method')
        except KeyError:
            raise exception.ParamsError("URL or METHOD missed!")

        resp_obj = self.client.request(url=url, method=method, **req_kwargs)
        response.extract_response(resp_obj, self.context)
        diff_content = response.diff_response(resp_obj, testcase['response'])
        success = False if diff_content else True
        return success, diff_content

    def run_testset(self, testset):
        """ run single testset, including one or several testcases.
        @param (dict) testset
            {
                "name": "testset description",
                "config": {
                    "name": "testset description",
                    "requires": [],
                    "function_binds": {},
                    "variable_binds": []
                },
                "testcases": [
                    {
                        "name": "testcase description",
                        "variable_binds": {}, # override
                        "request": {},
                        "response": {}
                    },
                    testcase12
                ]
            }
        @return (list) test results of testcases
            [
                (success, diff_content),    # testcase1
                (success, diff_content)     # testcase2
            ]
        """
        results = []

        config_dict = testset.get("config", {})
        self.pre_config(config_dict)
        testcases = testset.get("testcases", [])
        for testcase in testcases:
            result = self.run_test(testcase)
            results.append(result)

        return results

    def run_testsets(self, testsets):
        """ run testsets, including one or several testsets.
        @param testsets
            [
                testset1,
                testset2,
            ]
        @return (list) test results of testsets
            [
                [   # testset1
                    (success, diff_content),    # testcase11
                    (success, diff_content)     # testcase12
                ],
                [   # testset2
                    (success, diff_content),    # testcase21
                    (success, diff_content)     # testcase22
                ]
            ]
        """
        return [self.run_testset(testset) for testset in testsets]