def _fill_verdict(verdict, result, testcase, records): # xunit Pass maps to Passed in Polarion if verdict in Verdicts.PASS: records['passed'] += 1 # xunit Failure maps to Failed in Polarion elif verdict in Verdicts.FAIL: records['failures'] += 1 verdict_data = {'type': 'failure'} if result.get('comment'): verdict_data['message'] = utils.get_unicode_str( result['comment']) ElementTree.SubElement(testcase, 'failure', verdict_data) # xunit Error maps to Blocked in Polarion elif verdict in Verdicts.SKIP: records['skipped'] += 1 verdict_data = {'type': 'error'} if result.get('comment'): verdict_data['message'] = utils.get_unicode_str( result['comment']) ElementTree.SubElement(testcase, 'error', verdict_data) # xunit Skipped maps to Waiting in Polarion elif verdict in Verdicts.WAIT: records['waiting'] += 1 verdict_data = {'type': 'skipped'} if result.get('comment'): verdict_data['message'] = utils.get_unicode_str( result['comment']) ElementTree.SubElement(testcase, 'skipped', verdict_data)
def _add_test_steps(parent: etree.Element, testcase_data: dict) -> None: steps = testcase_data.get("testSteps") results = testcase_data.get("expectedResults") or {} params = testcase_data.get("params") or () test_steps = etree.SubElement(parent, "test-steps") if steps and testcase_data["caseautomation"] != "automated": for index, step in enumerate(steps): test_step = etree.SubElement(test_steps, "test-step") test_step_col = etree.SubElement(test_step, "test-step-column", id="step") test_step_col.text = utils.get_unicode_str(step) test_res_col = etree.SubElement(test_step, "test-step-column", id="expectedResult") try: test_res_col.text = utils.get_unicode_str(results[index]) except IndexError: test_res_col.text = "" else: test_step = etree.SubElement(test_steps, "test-step") test_step_col = etree.SubElement(test_step, "test-step-column", id="step") for param in params: param_el = etree.Element("parameter", name=param, scope="local") test_step_col.append(param_el)
def _fill_properties(verdict, result, testcase, testcase_id, testcase_title): """Adds properties into testcase element.""" properties = etree.SubElement(testcase, "properties") etree.SubElement( properties, "property", {"name": "polarion-testcase-id", "value": testcase_id or testcase_title}, ) if verdict in Verdicts.PASS and result.get("comment"): etree.SubElement( properties, "property", { "name": "polarion-testcase-comment", "value": utils.get_unicode_str(result["comment"]), }, ) for param, value in six.iteritems(result.get("params") or {}): etree.SubElement( properties, "property", { "name": "polarion-parameter-{}".format(param), "value": utils.get_unicode_str(value), }, )
def _fill_verdict(verdict: str, result: dict, testcase: etree.Element, records: dict) -> None: # XUnit Pass maps to Passed in Polarion if verdict in Verdicts.PASS: records["passed"] += 1 # XUnit Failure maps to Failed in Polarion elif verdict in Verdicts.FAIL: records["failures"] += 1 verdict_data = {"type": "failure"} if result.get("comment"): verdict_data["message"] = utils.get_unicode_str( result["comment"]) etree.SubElement(testcase, "failure", utils.sorted_dict(verdict_data)) # XUnit Error maps to Blocked in Polarion elif verdict in Verdicts.SKIP: records["skipped"] += 1 verdict_data = {"type": "error"} if result.get("comment"): verdict_data["message"] = utils.get_unicode_str( result["comment"]) etree.SubElement(testcase, "error", utils.sorted_dict(verdict_data)) # XUnit Skipped maps to Waiting in Polarion elif verdict in Verdicts.WAIT: records["waiting"] += 1 verdict_data = {"type": "skipped"} if result.get("comment"): verdict_data["message"] = utils.get_unicode_str( result["comment"]) etree.SubElement(testcase, "skipped", utils.sorted_dict(verdict_data))
def _requirement_element(self, parent_element: etree.Element, req_data: dict) -> None: """Add requirement XML element.""" req_data = self.requirement_transform.transform(req_data) if not req_data: return title = req_data.get("title") req_id = req_data.get("id") if not self._check_lookup_prop(req_id): LOGGER.warning( "Skipping requirement `%s`, data missing for selected lookup method", title) return attrs, custom_fields = self._classify_data(req_data) # For testing purposes, the order of fields in resulting XML # needs to be always the same. attrs = utils.sorted_dict(attrs) custom_fields = utils.sorted_dict(custom_fields) requirement = etree.SubElement(parent_element, "requirement", attrs) title_el = etree.SubElement(requirement, "title") title_el.text = utils.get_unicode_str(title) description = req_data.get("description") if description: description_el = etree.SubElement(requirement, "description") description_el.text = utils.get_unicode_str(description) self._fill_custom_fields(requirement, custom_fields)
def _fill_out_err(result: dict, testcase: etree.Element) -> None: """Add stdout and stderr if present.""" if result.get("stdout"): system_out = etree.SubElement(testcase, "system-out") system_out.text = utils.get_unicode_str(result["stdout"]) if result.get("stderr"): system_err = etree.SubElement(testcase, "system-err") system_err.text = utils.get_unicode_str(result["stderr"])
def _fill_out_err(result, testcase): """Adds stdout and stderr if present.""" if result.get('stdout'): system_out = ElementTree.SubElement(testcase, 'system-out') system_out.text = utils.get_unicode_str(result['stdout']) if result.get('stderr'): system_err = ElementTree.SubElement(testcase, 'system-err') system_err.text = utils.get_unicode_str(result['stderr'])
def _gen_testcase(self, parent_element, result, records): """Creates XML element for given testcase result and update testcases records.""" if self._transform_func: result = self._transform_func(result) if not result: return verdict = result.get('verdict', '').strip().lower() if verdict not in Verdicts.PASS + Verdicts.FAIL + Verdicts.SKIP + Verdicts.WAIT: return testcase_id = result.get('id') testcase_title = result.get('title') if self._lookup_prop: if not testcase_id and self._lookup_prop != 'name': return if not testcase_title and self._lookup_prop == 'name': return else: if testcase_id: self._lookup_prop = 'id' elif testcase_title: self._lookup_prop = 'name' testcase_time = float( result.get('time') or result.get('duration') or 0) records['time'] += testcase_time testcase_data = { 'name': testcase_title or testcase_id, 'time': str(testcase_time) } if result.get('classname'): testcase_data['classname'] = result['classname'] testcase = ElementTree.SubElement(parent_element, 'testcase', testcase_data) self._fill_verdict(verdict, result, testcase, records) if result.get('stdout'): system_out = ElementTree.SubElement(testcase, 'system-out') system_out.text = utils.get_unicode_str(result['stdout']) if result.get('stderr'): system_err = ElementTree.SubElement(testcase, 'system-err') system_err.text = utils.get_unicode_str(result['stderr']) properties = ElementTree.SubElement(testcase, 'properties') ElementTree.SubElement(properties, 'property', { 'name': 'polarion-testcase-id', 'value': testcase_id or testcase_title }) if verdict in Verdicts.PASS and result.get('comment'): ElementTree.SubElement( properties, 'property', { 'name': 'polarion-testcase-comment', 'value': utils.get_unicode_str(result['comment']) })
def _set_property(xml_root, name, value, properties=None): """Sets property to specified value.""" if properties is None: properties = xml_root.find("properties") for prop in properties: if prop.get("name") == name: prop.set("value", utils.get_unicode_str(value)) break else: etree.SubElement( properties, "property", {"name": name, "value": utils.get_unicode_str(value)} )
def _testcase_element(self, parent_element: etree.Element, testcase_data: dict, records: list) -> None: """Add testcase XML element.""" nodeid = testcase_data.get("nodeid", "") if not self._is_whitelisted(nodeid): LOGGER.debug("Skipping blacklisted node: %s", nodeid) return testcase_data = self.testcases_transform.transform(testcase_data) if not testcase_data: return if testcase_data.get("ignored"): LOGGER.debug("Skipping ignored node: %s", nodeid) return testcase_title = testcase_data.get("title") self._set_lookup_prop(testcase_data) if not self._check_lookup_prop(testcase_data): LOGGER.warning( "Skipping testcase `%s`, data missing for selected lookup method", testcase_data.get("id") or testcase_title, ) return # make sure that ID is set even for "name" lookup method testcase_data["id"] = self._get_testcase_id(testcase_data) records.append(testcase_data["id"]) attrs, custom_fields = self._classify_data(testcase_data) # For testing purposes, the order of fields in resulting XML # needs to be always the same. attrs = utils.sorted_dict(attrs) custom_fields = utils.sorted_dict(custom_fields) testcase = etree.SubElement(parent_element, "testcase", attrs) title_el = etree.SubElement(testcase, "title") title_el.text = utils.get_unicode_str(testcase_title) description = testcase_data.get("description") if description: description_el = etree.SubElement(testcase, "description") description_el.text = utils.get_unicode_str(description) self._add_test_steps(testcase, testcase_data) self._fill_custom_fields(testcase, custom_fields) self._add_linked_items(testcase, testcase_data)
def _fill_testsuites_response_property(xml_root, name, value): """Returns testsuites response property and fills it if missing.""" properties = xml_root.find("properties") for prop in properties: prop_name = prop.get("name", "") if "polarion-response-" in prop_name: offset = len("polarion-response-") response_property = (prop_name[offset:], utils.get_unicode_str(prop.get("value"))) break else: prop_name = "polarion-response-{}".format(name) etree.SubElement( properties, "property", {"name": prop_name, "value": utils.get_unicode_str(value)} ) response_property = (name, value) return response_property
def test_top_element(config_prop, records_ids): exporter = XunitExport("5_8_0_17", records_ids, config_prop, transform_func=lambda: None) top_element = exporter._top_element() parsed = "<testsuites><!--Generated for testrun 5_8_0_17--></testsuites>".strip( ) top_element_str = get_unicode_str( etree.tostring(top_element, encoding="utf-8").strip()) assert top_element_str == parsed
def test_top_element(config_prop, records_ids): exporter = XunitExport('5_8_0_17', records_ids, config_prop, transform_func=lambda: None) top_element = exporter._top_element() parsed = '<testsuites><!--Generated for testrun 5_8_0_17--></testsuites>'.strip( ) top_element_str = get_unicode_str( ElementTree.tostring(top_element, 'utf-8').strip()) assert top_element_str == parsed
def _fill_properties(verdict, result, testcase, testcase_id, testcase_title): """Adds properties into testcase element.""" properties = ElementTree.SubElement(testcase, 'properties') ElementTree.SubElement(properties, 'property', { 'name': 'polarion-testcase-id', 'value': testcase_id or testcase_title }) if verdict in Verdicts.PASS and result.get('comment'): ElementTree.SubElement( properties, 'property', { 'name': 'polarion-testcase-comment', 'value': utils.get_unicode_str(result['comment']) }) for param, value in six.iteritems(result.get('params', {}) or {}): ElementTree.SubElement( properties, 'property', { 'name': 'polarion-parameter-{}'.format(param), 'value': utils.get_unicode_str(value) })
def __init__(self, config: dict, transform_func: Optional[Callable] = None) -> None: self.config = config self._transform_func = transform_func or transform_projects.get_requirements_transform( config) default_fields = self.config.get("requirements_default_fields") or {} default_fields = { k: utils.get_unicode_str(v) for k, v in default_fields.items() if v } self.default_fields = utils.sorted_dict(default_fields)
def test_properties_lookup_config(self, config_prop, records_names): new_config = copy.deepcopy(config_prop) new_config['xunit_import_properties']['polarion-lookup-method'] = "id" exporter = XunitExport('5_8_0_17', records_names, new_config, transform_func=lambda: None) top_element = exporter._top_element() properties_element = exporter._properties_element(top_element) exporter._fill_lookup_prop(properties_element) properties_str = get_unicode_str( ElementTree.tostring(properties_element, 'utf-8').strip()) assert '<property name="polarion-lookup-method" value="id" />' in properties_str
def test_properties_lookup_config(self, records_names): new_config = copy.deepcopy(self.config_prop) new_config["xunit_import_properties"]["polarion-lookup-method"] = "id" exporter = XunitExport("5_8_0_17", records_names, new_config, transform_func=lambda: None) top_element = exporter._top_element() properties_element = exporter._properties_element(top_element) exporter._fill_lookup_prop(properties_element) properties_str = get_unicode_str( etree.tostring(properties_element, encoding="utf-8").strip()) assert '<property name="polarion-lookup-method" value="id"/>' in properties_str
def _fill_custom_fields(parent, custom_fields): if not custom_fields: return custom_fields_el = etree.SubElement(parent, "custom-fields") for field, content in six.iteritems(custom_fields): etree.SubElement( custom_fields_el, "custom-field", { "id": field, "content": utils.get_unicode_str(content) }, )
def _fill_properties( verdict: str, result: dict, testcase: etree.Element, testcase_id: Optional[str], testcase_title: Optional[str], ) -> None: """Add properties into testcase element.""" id_value = testcase_id or testcase_title if not id_value: raise Dump2PolarionException( "Neither `testcase_id` not `testcase_title` has valid value.") properties = etree.SubElement(testcase, "properties") etree.SubElement(properties, "property", { "name": "polarion-testcase-id", "value": id_value }) if verdict in Verdicts.PASS and result.get("comment"): etree.SubElement( properties, "property", { "name": "polarion-testcase-comment", "value": utils.get_unicode_str(result["comment"]), }, ) params = result.get("params") or {} for param, value in params.items(): etree.SubElement( properties, "property", { "name": "polarion-parameter-{}".format(param), "value": utils.get_unicode_str(value), }, )
def _fill_custom_fields(parent: etree.Element, custom_fields: dict) -> None: if not custom_fields: return custom_fields_el = etree.SubElement(parent, "custom-fields") for field, content in custom_fields.items(): etree.SubElement( custom_fields_el, "custom-field", utils.sorted_dict({ "id": field, "content": utils.get_unicode_str(content) }), )
def test_properties_element(self, config_prop, records_ids): exporter = XunitExport('5_8_0_17', records_ids, config_prop, transform_func=lambda: None) top_element = exporter._top_element() properties_element = exporter._properties_element(top_element) parsed = ( '<properties>' '<property name="polarion-testrun-id" value="5_8_0_17" />' '<property name="polarion-dry-run" value="False" />' '<property name="polarion-project-id" value="RHCF3" />' '<property name="polarion-response-test" value="test" />' '<property name="polarion-testrun-status-id" value="inprogress" />' '</properties>'.strip()) properties_str = get_unicode_str( ElementTree.tostring(properties_element, 'utf-8').strip()) assert properties_str == parsed
def xunit_fill_testrun_id(xml_root, testrun_id): """Adds the polarion-testrun-id property when it's missing.""" properties = _get_testrun_properties(xml_root) if properties is None: return for prop in properties: if prop.get("name") == "polarion-testrun-id": break else: if not testrun_id: raise Dump2PolarionException( "Failed to submit results to Polarion - missing testrun id" ) etree.SubElement( properties, "property", {"name": "polarion-testrun-id", "value": utils.get_unicode_str(testrun_id)}, )
def _fill_non_testsuites_response_property(xml_root, name, value): """Returns testcases/requirements response property and fills it if missing.""" properties = xml_root.find("response-properties") if properties is None: properties = etree.Element("response-properties") # response properties needs to be on top! xml_root.insert(0, properties) for prop in properties: if prop.tag == "response-property": prop_name = prop.get("name") prop_value = prop.get("value") if prop_name and prop_value: response_property = (prop_name, utils.get_unicode_str(prop_value)) break else: etree.SubElement(properties, "response-property", {"name": name, "value": value}) response_property = (name, value) return response_property
def __init__(self, testcases_data, config, transform_func=None): self.testcases_data = testcases_data self.config = config self._lookup_prop = "" self._transform_func = transform_func or transform_projects.get_testcases_transform( config) default_fields = self.config.get("default_fields") or {} default_fields = [(key, utils.get_unicode_str(value)) for key, value in default_fields.items() if value] default_fields.sort() self.default_fields = OrderedDict(default_fields) self.known_custom_fields = set(self.CUSTOM_FIELDS) self.known_custom_fields.update(self.config.get("custom_fields") or ()) self._compiled_whitelist = None self._compiled_blacklist = None if self.config.get("whitelisted_tests"): self._compiled_whitelist = re.compile( "(" + ")|(".join(self.config.get("whitelisted_tests")) + ")") if self.config.get("blacklisted_tests"): self._compiled_blacklist = re.compile( "(" + ")|(".join(self.config.get("blacklisted_tests")) + ")")
def _prettify(top_element): """Returns a pretty-printed XML.""" rough_string = ElementTree.tostring(top_element, 'utf-8') reparsed = minidom.parseString(rough_string) return utils.get_unicode_str( reparsed.toprettyxml(indent=' ', encoding='utf-8'))
def test_get_unicode_char(self): unicode_str = utils.get_unicode_str(u'®') assert unicode_str == u'®'
def test_get_unicode_basestring(self): unicode_str = utils.get_unicode_str('@'.encode('ascii')) assert unicode_str == u'@'
def test_get_unicode_basestring(self): unicode_str = utils.get_unicode_str("@".encode("ascii")) assert unicode_str == "@"
def test_get_unicode_char(self): unicode_str = utils.get_unicode_str("®") assert unicode_str == "®"
def test_get_unicode_num(self): unicode_str = utils.get_unicode_str(42) assert unicode_str == "42"