def test_get_parsed_request(self): test_runner = runner.Runner() testcase = { "import_module_items": ["tests.data.debugtalk"], "variables": [{ "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" } } parsed_request = test_runner.init_config(testcase, level="testcase") 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["variables"][2]["data"]) self.assertEqual(parsed_request["headers"]["secret_key"], "DebugTalk")
def test_get_parsed_request(self): test_runner = runner.Runner() testcase = { "variables": [ {"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" } } from tests import debugtalk self.context.import_module_items(debugtalk) self.context.bind_variables(testcase["variables"]) parsed_request = self.context.get_parsed_request(testcase["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["variables"][2]["data"]) self.assertEqual(parsed_request["headers"]["secret_key"], "DebugTalk")
def test_run_testcase_with_hooks_assignment(self): config_dict = { "name": "basic test with httpbin", "base_url": HTTPBIN_SERVER } test = { "name": "modify request headers", "request": { "url": "/anything", "method": "POST", "headers": { "user_agent": "iOS/10.3", "os_platform": "ios" }, "data": "a=1&b=2" }, "setup_hooks": [ {"total": "${sum_two(1, 5)}"} ], "validate": [ {"check": "status_code", "expect": 200} ] } test_runner = runner.Runner(config_dict, self.debugtalk_functions) test_runner.run_test(test) test_variables_mapping = test_runner.session_context.test_variables_mapping self.assertEqual(test_variables_mapping["total"], 6) self.assertEqual(test_variables_mapping["request"]["data"], "a=1&b=2")
def test_run_testset_with_hooks_modify_request(self): config_dict = { "path": os.path.join(os.getcwd(), __file__), "name": "basic test with httpbin", "request": { "base_url": "http://127.0.0.1:3458/" } } test = { "name": "modify request headers", "request": { "url": "/anything", "method": "POST", "headers": { "content-type": "application/json", "user_agent": "iOS/10.3", "os_platform": "ios" }, "json": { "sign": "f1219719911caae89ccc301679857ebfda115ca2" } }, "setup_hooks": ["${modify_headers_os_platform($request, android)}"], "validate": [{ "check": "status_code", "expect": 200 }, { "check": "content.headers.Os-Platform", "expect": "android" }] } test_runner = runner.Runner(config_dict) test_runner.run_test(test)
def test_validate_exception(self): testcases = [{ "config": { 'name': "test validation" }, "teststeps": [{ "name": "test validation", "request": { "url": "http://127.0.0.1:5000/", "method": "GET", }, "variables": { "resp_status_code": 200, "resp_body_success": True }, "validate": [{ "eq": ["$resp_status_code", 201] }, { "check": "$resp_status_code", "expect": 201 }, { "check": "$resp_body_success", "comparator": "eq", "expect": True }] }] }] tests_mapping = {"testcases": testcases} testcases = parser.parse_tests(tests_mapping) parsed_testcase = testcases[0] test_runner = runner.Runner(parsed_testcase["config"]) teststep = parsed_testcase["teststeps"][0] with self.assertRaises(exceptions.ValidationFailure): test_runner.run_test(teststep)
def test_run_single_testcase(self): testcase_file_path_list = [ os.path.join( os.getcwd(), 'tests/data/demo_testcase_hardcode.yml'), os.path.join( os.getcwd(), 'tests/data/demo_testcase_hardcode.json') ] for testcase_file_path in testcase_file_path_list: testcases = loader.load_file(testcase_file_path) config_dict = { "variables": self.debugtalk_module["variables"], "functions": self.debugtalk_module["functions"] } test_runner = runner.Runner(config_dict) test = testcases[0]["test"] test_runner.run_test(test) test = testcases[1]["test"] test_runner.run_test(test) test = testcases[2]["test"] test_runner.run_test(test)
def __init__(self, testset): super(ApiTestSuite, self).__init__() self.test_runner = runner.Runner() self.config_dict = testset.get("config", {}) self.test_runner.init_config(self.config_dict, level="testset") testcases = testset.get("testcases", []) self._add_tests_to_suite(testcases)
def test_run_testcase_with_hooks_modify_request(self): config_dict = { "name": "basic test with httpbin", "variables": self.debugtalk_module["variables"], "functions": self.debugtalk_module["functions"], "request": { "base_url": HTTPBIN_SERVER } } test = { "name": "modify request headers", "request": { "url": "/anything", "method": "POST", "headers": { "content-type": "application/json", "user_agent": "iOS/10.3", "os_platform": "ios" }, "json": { "sign": "f1219719911caae89ccc301679857ebfda115ca2" } }, "setup_hooks": [ "${modify_headers_os_platform($request, android)}" ], "validate": [ {"check": "status_code", "expect": 200}, {"check": "content.headers.Os-Platform", "expect": "android"} ] } test_runner = runner.Runner(config_dict) test_runner.run_test(test)
def __init__(self, testset, variables_mapping=None, http_client_session=None): super(ApiTestSuite, self).__init__() self.config_dict = testset.get("config", {}) variables = self.config_dict.get("variables", []) variables_mapping = variables_mapping or {} self.config_dict["variables"] = utils.override_variables_binds( variables, variables_mapping) parameters = self.config_dict.get("parameters", []) cartesian_product_parameters = testcase.gen_cartesian_product_parameters( parameters, self.config_dict["path"]) or [{}] for parameter_mapping in cartesian_product_parameters: if parameter_mapping: self.config_dict["variables"] = utils.override_variables_binds( self.config_dict["variables"], parameter_mapping) self.test_runner = runner.Runner(self.config_dict, http_client_session) testcases = testset.get("testcases", []) self._add_tests_to_suite(testcases)
def test_run_testcase_with_hooks(self): start_time = time.time() testcases = [ { "config": { "name": "basic test with httpbin", "base_url": HTTPBIN_SERVER, "setup_hooks": [ "${sleep(0.5)}", "${hook_print(setup)}" ], "teardown_hooks": [ "${sleep(1)}", "${hook_print(teardown)}" ] }, "teststeps": [ { "name": "get token", "request": { "url": "http://127.0.0.1:5000/api/get-token", "method": "POST", "headers": { "content-type": "application/json", "user_agent": "iOS/10.3", "device_sn": "HZfFBh6tU59EdXJ", "os_platform": "ios", "app_version": "2.8.6" }, "json": { "sign": "5188962c489d1a35effa99e9346dd5efd4fdabad" } }, "validate": [ {"check": "status_code", "expect": 200} ] } ] } ] tests_mapping = { "project_mapping": { "functions": self.debugtalk_functions }, "testcases": testcases } parsed_testcases = parser.parse_tests(tests_mapping) parsed_testcase = parsed_testcases[0] test_runner = runner.Runner(parsed_testcase["config"]) end_time = time.time() # check if testcase setup hook executed self.assertGreater(end_time - start_time, 0.5) start_time = time.time() test_runner.run_test(parsed_testcase["teststeps"][0]) end_time = time.time() # testcase teardown hook has not been executed now self.assertLess(end_time - start_time, 1)
def setUp(self): self.test_runner = runner.Runner() self.reset_all() self.testcase_file_path_list = [ os.path.join(os.getcwd(), 'tests/data/demo_testset_hardcode.yml'), os.path.join(os.getcwd(), 'tests/data/demo_testset_hardcode.json') ]
def test_exec_content_functions(self): test_runner = runner.Runner() content = "${sleep(1)}" start_time = time.time() test_runner.context.eval_content(content) end_time = time.time() elapsed_time = end_time - start_time self.assertGreater(elapsed_time, 1)
def test_bugfix_type_match(self): testcase_file_path = os.path.join( os.getcwd(), 'tests/data/bugfix_type_match.yml') tests_mapping = loader.load_cases(testcase_file_path) parsed_testcases = parser.parse_tests(tests_mapping) parsed_testcase = parsed_testcases[0] test_runner = runner.Runner(parsed_testcase["config"]) test_runner.run_test(parsed_testcase["teststeps"][0])
def _add_tests(self, testcases): """ initialize testcase with Runner() and add to test suite. Args: testcases (list): parsed testcases list Returns: tuple: unittest.TestSuite() """ def _add_teststep(test_runner, config, teststep_dict): """ add teststep to testcase. """ def test(self): try: test_runner.run_test(teststep_dict) except exceptions.MyBaseFailure as ex: self.fail(str(ex)) finally: if hasattr(test_runner.http_client_session, "meta_data"): self.meta_data = test_runner.http_client_session.meta_data self.meta_data["validators"] = test_runner.evaluated_validators test_runner.http_client_session.init_meta_data() try: teststep_dict["name"] = parser.parse_data( teststep_dict["name"], config.get("variables", {}), config.get("functions", {}) ) except exceptions.VariableNotFound: pass test.__doc__ = teststep_dict["name"] return test test_suite = unittest.TestSuite() for testcase in testcases: config = testcase.get("config", {}) test_runner = runner.Runner(config, self.http_client_session) TestSequense = type('TestSequense', (unittest.TestCase,), {}) teststeps = testcase.get("teststeps", []) for index, teststep_dict in enumerate(teststeps): for times_index in range(int(teststep_dict.get("times", 1))): # suppose one testcase should not have more than 9999 steps, # and one step should not run more than 999 times. test_method_name = 'test_{:04}_{:03}'.format(index, times_index) test_method = _add_teststep(test_runner, config, teststep_dict) setattr(TestSequense, test_method_name, test_method) loaded_testcase = self.test_loader.loadTestsFromTestCase(TestSequense) setattr(loaded_testcase, "config", config) setattr(loaded_testcase, "teststeps", testcase.get("teststeps", [])) setattr(loaded_testcase, "runner", test_runner) test_suite.addTest(loaded_testcase) return test_suite
def _add_tests(self, tests_mapping): """ initialize testcase with Runner() and add to test suite. Args: tests_mapping (dict): project info and testcases list. Returns: unittest.TestSuite() """ def _add_test(test_runner, test_dict): """ add test to testcase. """ def test(self): try: test_runner.run_test(test_dict) except exceptions.MyBaseFailure as ex: self.fail(str(ex)) finally: self.meta_datas = test_runner.meta_datas if "config" in test_dict: # run nested testcase test.__doc__ = test_dict["config"].get("name") else: # run api test test.__doc__ = test_dict.get("name") return test test_suite = unittest.TestSuite() functions = tests_mapping.get("project_mapping", {}).get("functions", {}) for testcase in tests_mapping["testcases"]: config = testcase.get("config", {}) test_runner = runner.Runner(config, functions) TestSequense = type('TestSequense', (unittest.TestCase, ), {}) tests = testcase.get("teststeps", []) for index, test_dict in enumerate(tests): for times_index in range(int(test_dict.get("times", 1))): # suppose one testcase should not have more than 9999 steps, # and one step should not run more than 999 times. test_method_name = 'test_{:04}_{:03}'.format( index, times_index) test_method = _add_test(test_runner, test_dict) setattr(TestSequense, test_method_name, test_method) loaded_testcase = self.test_loader.loadTestsFromTestCase( TestSequense) setattr(loaded_testcase, "config", config) setattr(loaded_testcase, "teststeps", tests) setattr(loaded_testcase, "runner", test_runner) test_suite.addTest(loaded_testcase) return test_suite
def setUp(self): loader.load_project_tests(os.path.join(os.getcwd(), "tests")) self.debugtalk_module = loader.project_mapping["debugtalk"] config_dict = { "variables": self.debugtalk_module["variables"], "functions": self.debugtalk_module["functions"] } self.test_runner = runner.Runner(config_dict) self.reset_all()
def __init__(self, testset): super(ApiTestSuite, self).__init__() #生成一个Runner的实例:test_runner,Runner包含了各种执行测试用例的方法 self.test_runner = runner.Runner() #从testset里读取config信息,作为字典config_dict保存 self.config_dict = testset.get("config", {}) #执行Runner类的init_config方法,当level为testset时,处理config_dict里的值为常规参数类型并作为字典返回 self.test_runner.init_config(self.config_dict, level="testset") testcases = testset.get("testcases", []) self._add_tests_to_suite(testcases)
def setUp(self): project_mapping = loader.load_project_data(os.path.join(os.getcwd(), "tests")) self.debugtalk_functions = project_mapping["functions"] config = { "name": "XXX", "base_url": "http://127.0.0.1", "verify": False } self.test_runner = runner.Runner(config) self.reset_all()
def __init__(self, testset, variables_mapping=None, http_client_session=None): super(TestSuite, self).__init__() self.test_runner_list = [] config_dict = testset.get("config", {}) self.output_variables_list = config_dict.get("output", []) self.testset_file_path = config_dict.get("path") config_dict_parameters = config_dict.get("parameters", []) config_dict_variables = config_dict.get("variables", []) variables_mapping = variables_mapping or {} config_dict_variables = utils.override_variables_binds( config_dict_variables, variables_mapping) config_parametered_variables_list = self._get_parametered_variables( config_dict_variables, config_dict_parameters) self.testcase_parser = testcase.TestcaseParser() testcases = testset.get("testcases", []) for config_variables in config_parametered_variables_list: # config level config_dict["variables"] = config_variables test_runner = runner.Runner(config_dict, http_client_session) for testcase_dict in testcases: testcase_dict = copy.copy(testcase_dict) # testcase level testcase_parametered_variables_list = self._get_parametered_variables( testcase_dict.get("variables", []), testcase_dict.get("parameters", [])) for testcase_variables in testcase_parametered_variables_list: testcase_dict["variables"] = testcase_variables # eval testcase name with bind variables variables = utils.override_variables_binds( config_variables, testcase_variables) self.testcase_parser.update_binded_variables(variables) try: testcase_name = self.testcase_parser.eval_content_with_bindings( testcase_dict["name"]) except (AssertionError, exception.ParamsError): logger.log_warning( "failed to eval testcase name: {}".format( testcase_dict["name"])) testcase_name = testcase_dict["name"] self.test_runner_list.append((test_runner, variables)) self._add_test_to_suite(testcase_name, test_runner, testcase_dict)
def test_run_validate_elapsed(self): testcases = [{ "config": {}, "teststeps": [{ "name": "get token", "request": { "url": "http://127.0.0.1:5000/api/get-token", "method": "POST", "headers": { "content-type": "application/json", "user_agent": "iOS/10.3", "device_sn": "HZfFBh6tU59EdXJ", "os_platform": "ios", "app_version": "2.8.6" }, "json": { "sign": "5188962c489d1a35effa99e9346dd5efd4fdabad" } }, "validate": [{ "check": "status_code", "expect": 200 }, { "check": "elapsed.seconds", "comparator": "lt", "expect": 1 }, { "check": "elapsed.days", "comparator": "eq", "expect": 0 }, { "check": "elapsed.microseconds", "comparator": "gt", "expect": 1000 }, { "check": "elapsed.total_seconds", "comparator": "lt", "expect": 1 }] }] }] tests_mapping = { "project_mapping": { "functions": self.debugtalk_functions }, "testcases": testcases } parsed_testcases = parser.parse_tests(tests_mapping) parsed_testcase = parsed_testcases[0] test_runner = runner.Runner(parsed_testcase["config"]) test_runner.run_test(parsed_testcase["teststeps"][0])
def test_run_single_testcase(self): testcase_file_path_list = [ os.path.join(os.getcwd(), 'tests/data/demo_testcase_hardcode.yml'), os.path.join(os.getcwd(), 'tests/data/demo_testcase_hardcode.json') ] for testcase_file_path in testcase_file_path_list: tests_mapping = loader.load_tests(testcase_file_path) parsed_testcases = parser.parse_tests(tests_mapping) parsed_testcase = parsed_testcases[0] test_runner = runner.Runner(parsed_testcase["config"]) test_runner.run_test(parsed_testcase["teststeps"][0]) test_runner.run_test(parsed_testcase["teststeps"][1]) test_runner.run_test(parsed_testcase["teststeps"][2])
def test_run_testcase_with_hooks(self): start_time = time.time() config_dict = { "name": "basic test with httpbin", "variables": self.debugtalk_module["variables"], "functions": self.debugtalk_module["functions"], "request": { "base_url": HTTPBIN_SERVER }, "setup_hooks": [ "${sleep_N_secs(0.5)}" "${hook_print(setup)}" ], "teardown_hooks": [ "${sleep_N_secs(1)}", "${hook_print(teardown)}" ] } test = { "name": "get token", "request": { "url": "http://127.0.0.1:5000/api/get-token", "method": "POST", "headers": { "content-type": "application/json", "user_agent": "iOS/10.3", "device_sn": "HZfFBh6tU59EdXJ", "os_platform": "ios", "app_version": "2.8.6" }, "json": { "sign": "f1219719911caae89ccc301679857ebfda115ca2" } }, "validate": [ {"check": "status_code", "expect": 200} ] } test_runner = runner.Runner(config_dict) end_time = time.time() # check if testcase setup hook executed self.assertGreater(end_time - start_time, 0.5) start_time = time.time() test_runner.run_test(test) test_runner.run_test(test) end_time = time.time() # testcase teardown hook has not been executed now self.assertLess(end_time - start_time, 1)
def test_run_testset_with_hooks(self): testcase_file_path = os.path.join(os.getcwd(), 'tests/httpbin/hooks.yml') start_time = time.time() config_dict = { "path": os.path.join(os.getcwd(), __file__), "name": "basic test with httpbin", "request": { "base_url": "http://127.0.0.1:3458/" }, "setup_hooks": ["${sleep_N_secs(0.5)}" "${hook_print(setup)}"], "teardown_hooks": ["${sleep_N_secs(1)}", "${hook_print(teardown)}"] } test = { "name": "get token", "request": { "url": "http://127.0.0.1:5000/api/get-token", "method": "POST", "headers": { "content-type": "application/json", "user_agent": "iOS/10.3", "device_sn": "HZfFBh6tU59EdXJ", "os_platform": "ios", "app_version": "2.8.6" }, "json": { "sign": "f1219719911caae89ccc301679857ebfda115ca2" } }, "validate": [{ "check": "status_code", "expect": 200 }] } test_runner = runner.Runner(config_dict) end_time = time.time() # check if testset setup hook executed self.assertGreater(end_time - start_time, 0.5) start_time = time.time() test_runner.run_test(test) test_runner.run_test(test) end_time = time.time() # testset teardown hook has not been executed now self.assertLess(end_time - start_time, 1)
def test_run_testcase_with_teardown_hooks_fail(self): testcases = [ { "config": { "name": "basic test with httpbin" }, "teststeps": [ { "name": "get token", "request": { "url": "http://127.0.0.1:5000/api/get-token2", "method": "POST", "headers": { "content-type": "application/json", "user_agent": "iOS/10.3", "device_sn": "HZfFBh6tU59EdXJ", "os_platform": "ios", "app_version": "2.8.6" }, "json": { "sign": "5188962c489d1a35effa99e9346dd5efd4fdabad" } }, "validate": [ {"check": "status_code", "expect": 404} ], "teardown_hooks": ["${teardown_hook_sleep_N_secs($response, 2)}"] } ] } ] tests_mapping = { "project_mapping": { "functions": self.debugtalk_functions }, "testcases": testcases } parsed_testcases = parser.parse_tests(tests_mapping) parsed_testcase = parsed_testcases[0] test_runner = runner.Runner(parsed_testcase["config"]) start_time = time.time() test_runner.run_test(parsed_testcase["teststeps"][0]) end_time = time.time() # check if teardown function executed self.assertGreater(end_time - start_time, 2)
def test_validate(self): testcases = [{ "config": { 'name': "test validation" }, "teststeps": [{ "name": "test validation", "request": { "url": "http://127.0.0.1:5000/", "method": "GET", }, "variables": { "resp_status_code": 200, "resp_body_success": True }, "validate": [{ "eq": ["$resp_status_code", 200] }, { "check": "$resp_status_code", "comparator": "eq", "expect": 200 }, { "check": "$resp_body_success", "expect": True }, { "check": "${is_status_code_200($resp_status_code)}", "expect": True }] }] }] from tests.debugtalk import is_status_code_200 tests_mapping = { "project_mapping": { "functions": { "is_status_code_200": is_status_code_200 } }, "testcases": testcases } testcases = parser.parse_tests(tests_mapping) parsed_testcase = testcases[0] test_runner = runner.Runner(parsed_testcase["config"]) teststep = parsed_testcase["teststeps"][0] test_runner.run_test(teststep)
def test_run_testcase_with_hooks_modify_request(self): testcases = [ { "config": { "name": "basic test with httpbin", "base_url": HTTPBIN_SERVER }, "teststeps": [ { "name": "modify request headers", "base_url": HTTPBIN_SERVER, "request": { "url": "/anything", "method": "POST", "headers": { "content-type": "application/json", "user_agent": "iOS/10.3" }, "json": { "os_platform": "ios", "sign": "5188962c489d1a35effa99e9346dd5efd4fdabad" } }, "setup_hooks": [ "${modify_request_json($request, android)}" ], "validate": [ {"check": "status_code", "expect": 200}, {"check": "content.json.os_platform", "expect": "android"} ] } ] } ] tests_mapping = { "project_mapping": { "functions": self.debugtalk_functions }, "testcases": testcases } parsed_testcases = parser.parse_tests(tests_mapping) parsed_testcase = parsed_testcases[0] test_runner = runner.Runner(parsed_testcase["config"]) test_runner.run_test(parsed_testcase["teststeps"][0])
def test_run_testcase_with_hooks_assignment(self): testcases = [ { "config": { "name": "basic test with httpbin", "base_url": HTTPBIN_SERVER }, "teststeps": [ { "name": "modify request headers", "base_url": HTTPBIN_SERVER, "request": { "url": "/anything", "method": "POST", "headers": { "user_agent": "iOS/10.3", "os_platform": "ios" }, "data": "a=1&b=2" }, "setup_hooks": [ {"total": "${sum_two(1, 5)}"} ], "validate": [ {"check": "status_code", "expect": 200} ] } ] } ] tests_mapping = { "project_mapping": { "functions": self.debugtalk_functions }, "testcases": testcases } parsed_testcases = parser.parse_tests(tests_mapping) parsed_testcase = parsed_testcases[0] test_runner = runner.Runner(parsed_testcase["config"]) test_runner.run_test(parsed_testcase["teststeps"][0]) test_variables_mapping = test_runner.session_context.test_variables_mapping self.assertEqual(test_variables_mapping["total"], 6) self.assertEqual(test_variables_mapping["request"]["data"], "a=1&b=2")
def __initialize(self, testcases): """ initialize test runner with parsed testcases. Args: testcases (list): testcases list Returns: tuple: (unittest.TextTestRunner(), unittest.TestSuite()) """ self.kwargs.setdefault("resultclass", report.HtmlTestResult) unittest_runner = unittest.TextTestRunner(**self.kwargs) testcases_list = [] loader = unittest.TestLoader() loaded_testcases = [] for testcase in testcases: config = testcase.get("config", {}) test_runner = runner.Runner(config, self.http_client_session) TestSequense = type('TestSequense', (unittest.TestCase, ), {}) teststeps = testcase.get("teststeps", []) for index, teststep_dict in enumerate(teststeps): for times_index in range(int(teststep_dict.get("times", 1))): # suppose one testcase should not have more than 9999 steps, # and one step should not run more than 999 times. test_method_name = 'test_{:04}_{:03}'.format( index, times_index) test_method = utils.add_teststep(test_runner, teststep_dict) setattr(TestSequense, test_method_name, test_method) loaded_testcase = loader.loadTestsFromTestCase(TestSequense) setattr(loaded_testcase, "config", config) setattr(loaded_testcase, "teststeps", testcase.get("teststeps", [])) setattr(loaded_testcase, "runner", test_runner) loaded_testcases.append(loaded_testcase) test_suite = unittest.TestSuite(loaded_testcases) return (unittest_runner, test_suite)
def _add_tests(self, testcases): """ initialize testcase with Runner() and add to test suite. 把测试用例加载到测试套件中 Args: testcases (list): testcases list. Returns: unittest.TestSuite() """ def _add_test(test_runner, test_dict): """ add test to testcase. 把步骤添加到用例,返回一个测试步骤 test_dict = parsed_testcases[0][teststeps][0] test_dict = { "name": "/mgmt/store/checkBusinessAddressIsExist", "request": { "headers": {"Authorization": "LazyString(${token_type} ${access_token})"}, "method": "GET", "params": { "provinceName": "LazyString(${provinceName})", "cityName": "LazyString(${cityName})", "areaName": LazyString(${areaName}), "streetName": LazyString(${streetName}), "detailAddress": LazyString(${detailAddress})}, "url": LazyString(${base_url}/mgmt/store/checkBusinessAddressIsExist), "verify": True }, "variables": { "provinceName": "广东省", "cityName": "广州市", "areaName": "海珠区", "streetName": "南州街道", "detailAddress": "广州市海珠区南洲街道新滘中路88号唯品同创汇6区东三街17号自编23号", "access_token": LazyString(${ENV(access_token)}), "token_type": LazyString(${ENV(token_type)}), "base_url": LazyString(${ENV(base_url)}) }, "validate": [LazyFunction(equals(status_code, 200))] } """ def test(self): try: test_runner.run_test(test_dict) pprint(test_runner) except exceptions.MyBaseFailure as ex: self.fail(str(ex)) finally: self.meta_datas = test_runner.meta_datas if "config" in test_dict: # run nested testcase 嵌套testcase运行:testcase引用了testcase test.__doc__ = test_dict["config"].get("name") variables = test_dict["config"].get("variables", {}) else: # run api test 运行api测试 testcase引用了api test.__doc__ = test_dict.get("name") variables = test_dict.get("variables", {}) if isinstance(test.__doc__, parser.LazyString): #懒惰的字符串:名字中有引用的变量 try: parsed_variables = parser.parse_variables_mapping( variables) # 所有的变量字典 test.__doc__ = parser.parse_lazy_data( # 找到引用变量对应的值 test.__doc__, parsed_variables) except exceptions.VariableNotFound: test.__doc__ = str(test.__doc__) # 返回函数<function HttpRunner._add_tests.<locals>._add_test.<locals>.test at 0x000002D69C38A550> return test test_suite = unittest.TestSuite() # 用例集的子类 for testcase in testcases: #遍历用例中引用的每一个用例 config = testcase.get("config", {}) # <httprunner.runner.Runner object at 0x000002629251F520> test_runner = runner.Runner(config) TestSequense = type('TestSequense', (unittest.TestCase, ), {}) #创建测试用例:unittest.TestCase子类 tests = testcase.get("teststeps", []) # 测试用例 for index, test_dict in enumerate(tests): # 遍历每一个测试步骤 times = test_dict.get("times", 1) try: times = int(times) except ValueError: raise exceptions.ParamsError( "times should be digit, given: {}".format(times)) for times_index in range(times): #根据times设置,运行一个测试步骤N次 # suppose one testcase should not have more than 9999 steps, # 假设一个测试用例不应该有超过9999个步骤 # and one step should not run more than 999 times. # 一个步骤不应该运行超过999次 test_method_name = 'test_{:04}_{:03}'.format( index, times_index) # 测试方法名 test_method = _add_test(test_runner, test_dict) # 测试方法 setattr(TestSequense, test_method_name, test_method) #加载测试方法到测试用例中:unittest.TestCase子类 loaded_testcase = self.test_loader.loadTestsFromTestCase( TestSequense) # 加载测试用例到用例集(小集:测试用例) setattr(loaded_testcase, "config", config) # 加载属性到用例集(小集:测试用例) setattr(loaded_testcase, "teststeps", tests) # 加载属性到用例集(小集:测试用例) setattr(loaded_testcase, "runner", test_runner) # 加载运行方法到用例集(小集:测试用例) test_suite.addTest(loaded_testcase) # 加载用例集(小集:测试用例)到大用例集 return test_suite
def _add_tests(self, testcases): """ initialize testcase with Runner() and add to test suite. Args: testcases (list): testcases list. Returns: unittest.TestSuite() """ def _add_test(test_runner, test_dict): """ add test to testcase. """ def test(self): try: test_runner.run_test(test_dict) except exceptions.MyBaseFailure as ex: self.fail(str(ex)) finally: self.meta_datas = test_runner.meta_datas if "config" in test_dict: # run nested testcase test.__doc__ = test_dict["config"].get("name") variables = test_dict["config"].get("variables", {}) else: # run api test test.__doc__ = test_dict.get("name") variables = test_dict.get("variables", {}) if isinstance(test.__doc__, parser.LazyString): try: parsed_variables = parser.parse_variables_mapping( variables) test.__doc__ = parser.parse_lazy_data( test.__doc__, parsed_variables) except exceptions.VariableNotFound: test.__doc__ = str(test.__doc__) return test test_suite = unittest.TestSuite() for testcase in testcases: config = testcase.get("config", {}) test_runner = runner.Runner(config) TestSequense = type('TestSequense', (unittest.TestCase, ), {}) tests = testcase.get("teststeps", []) for index, test_dict in enumerate(tests): times = test_dict.get("times", 1) try: times = int(times) except ValueError: raise exceptions.ParamsError( "times should be digit, given: {}".format(times)) for times_index in range(times): # suppose one testcase should not have more than 9999 steps, # and one step should not run more than 999 times. test_method_name = 'test_{:04}_{:03}'.format( index, times_index) test_method = _add_test(test_runner, test_dict) setattr(TestSequense, test_method_name, test_method) loaded_testcase = self.test_loader.loadTestsFromTestCase( TestSequense) setattr(loaded_testcase, "config", config) setattr(loaded_testcase, "teststeps", tests) setattr(loaded_testcase, "runner", test_runner) test_suite.addTest(loaded_testcase) return test_suite