def run(self): logging.basicConfig(level=DEFAULT_LOG_LEVEL, format=DEFAULT_LOG_LAYOUT) self.app_context = ApplicationContext(XmlConfig(self.xml)) self.xmlns = TestSuiteXmlLoader.get_xsd_default_namespace() runner_ele = self.app_context.config.root.find(self.xmlns + "testrunner") runner_id = runner_ele.get("id") failfast = get_boolean_from_string(runner_ele.get("failfast", "False")) context = TestContext() runner = TestRunner(runner_id, failfast=failfast, context=context) self.app_context.objects[str(runner.id)] = runner context_ele = runner_ele.find(self.xmlns + "context") if context_ele is not None: fixture_node = context_ele.find(self.xmlns + "fixture") if fixture_node is not None: fixture_def = ObjectDefParser.get_value_def(fixture_node) context.fixture = fixture_def.get_actual_value(self.app_context) listeners_ele = context_ele.find(self.xmlns + "listeners") if listeners_ele is not None: listeners_def = ObjectDefParser.get_value_def(listeners_ele) for listener in listeners_def.get_actual_value(self.app_context): context.add_listener(listener) for testsuite_ele in list(runner_ele.find(self.xmlns + "testsuites")): loader = TestSuiteXmlLoader(testsuite_ele) runner.add_testsuite(loader.as_dict()) self.app_context.get(runner_id).run()
def run(self): fs.mkdirs(self.output) log_conf = { "version": 1, "disable_existing_loggers": False, "formatters": {"verbose": {"format": DEFAULT_LOG_LAYOUT}}, "handlers": { "console": {"class": "logging.StreamHandler", "level": "DEBUG", "formatter": "verbose"}, "file_cli": { "class": "logging.handlers.RotatingFileHandler", "level": "DEBUG", "formatter": "verbose", "filename": os.path.join(self.output, "main.log"), "maxBytes": 50000000, "backupCount": 10, }, }, "root": {"level": "DEBUG", "handlers": ["console", "file_cli"]}, } logging.config.dictConfig(log_conf) runner_node = self.setting.etree.find("testrunner") failfast = True if self.failfast else get_boolean_from_string(runner_node.get("failfast", "False")) context = TestContext() runner = TestRunner(failfast=failfast, context=context) runner.context.add_listener(TestCaseLogFileInterceptor(self.output)) runner.context.add_listener(TestResultShelveInterceptor(os.path.join(self.output, "result.shelve"))) context_node = runner_node.find("context") if context_node is not None: for name, value in context_node.attrib.items(): setattr(context, name, value) testfixture_node = context_node.find("fixture") if testfixture_node is not None: if self.TestFixtureFactory is None: raise RuntimeError("Require TestFixtureFactory class to build the testfixture.") context.fixture = self.TestFixtureFactory.build_testfixture_by_element(testfixture_node) for testsuite_node in list(runner_node.find("testsuites")): loader = TestSuiteXmlLoader(testsuite_node) runner.add_testsuite(loader.as_dict()) try: runner.run() finally: report_node = self.setting.etree.find("report") summary = self.setting.get("//report/summary/text()") tester = self.setting.get("//report/tester/text()") template = report_node.get("template") report = SimpleHtmlReporter(runner.result, runner.context, template, summary, tester) output = report_node.get("output") or os.path.join(self.output, "report.html") report.generate(output)
def _generate_testcase_dict(self, element, params=None, container=None): testcase_dict = dict() for name, value in element.items(): if params is not None: template = string.Template(value) value = template.substitute(**params) if name == "is-prerequisite": value = get_boolean_from_string(value) testcase_dict[name.replace("-", "_")] = value parameters = [] for node in element.findall(self.__xmlns + "parameter"): parameters.append({"name": node.get("name"), "value": _get_parameter_node_value(node, params, container)}) testcase_dict["parameters"] = parameters return testcase_dict
def cast_value(self, old_value): new_value = old_value if not isinstance(old_value, self.type): if self.type is bool: new_value = get_boolean_from_string(old_value) elif self.type in (int, float, str): new_value = self.type(old_value) else: new_value = eval(old_value, self.context.globals, self.context.locals) logger.debug("eval('%s') result is: %s", old_value, new_value) if not isinstance(new_value, self.type): raise ValueError("%s's type is %s, does NOT match with %s" % (new_value, type(new_value), self.type)) if self.choice and new_value not in self.choice: raise ValueError("%s result in choice: %s" % (new_value, self.choice)) return new_value
def _generate_testsuite_dict_from_cls_loader_element(self, element, params=None, container=None): tests = [] module_name = element.get("module", "") module_parameters = self._generate_parameters_dict(element, params, container) class_path = "{xmlns}classes/{xmlns}class".format(xmlns=self.__xmlns) for class_element in element.findall(class_path): class_ignore_inherited = get_boolean_from_string(class_element.get("ignore-inherited", 'true')) if module_name: class_fullname = "{module}.{class_}".format(module=module_name, class_=class_element.get("name")) else: class_fullname = class_element.get("name") class_object = pydoc.locate(class_fullname) assert class_object is not None, "Can't find class by its fullname '{}'".format(class_fullname) class_parameters = self._generate_parameters_dict(class_element, params, container) method_elements = class_element.findall("{xmlns}methods/{xmlns}method".format(xmlns=self.__xmlns)) method_defines = [] if method_elements: for method_element in method_elements: method_defines.append(( method_element.get("name"), int(method_element.get("repeat", "1")), self._generate_parameters_dict(method_element, params, container) )) else: for method_name in get_test_method_names(class_object, class_ignore_inherited): method_defines.append((method_name, 1, {})) for method_name, method_repeat, method_parameters in method_defines: method_object = getattr(class_object, method_name) parameters = {} parameters.update(module_parameters) parameters.update(class_parameters) parameters.update(method_parameters) for case_dict in _generate_testcase_dicts_from_method(method_object, class_object, parameters): for _ in range(method_repeat): tests.append(case_dict) return {"name": module_name, "tests": tests}
def _handle_element(element, parent_params=None): if element.tag == self.__xmlns + "testsuite": tests.append(self._generate_testsuite_dict(element, parent_params, container)) elif element.tag == self.__xmlns + "testcase": tests.append(self._generate_testcase_dict(element, parent_params, container)) elif element.tag in (self.__xmlns + "pym-loader", self.__xmlns + "xml-loader", self.__xmlns + "cls-loader"): loader = element.tag.replace(self.__xmlns, "").replace("-", "_") method_name = "_generate_testsuite_dict_from_{}_element".format(loader) suite_dict = getattr(self, method_name)(element, parent_params, container) if get_boolean_from_string(element.get("as-testsuite", "false")): tests.append(suite_dict) else: tests.extend(suite_dict["tests"]) elif element.tag == self.__xmlns + "for": for_type = element.get("type") s = element.get("iter") l = [] if for_type == "expression": l = eval(s) elif for_type == "reference": container.get_object(s) else: raise ValueError("The attribute 'type' of <for> should be 'expression' or 'reference'") key = element.get("param") native_params = dict() if parent_params: native_params.update(parent_params) for val in l: if key is not None: native_params[key] = val for child in element: _handle_element(child, native_params) else: raise ValueError("Unsupported element tag: {}".format(element.tag))