def _write_test(self, file, test, suite_name): path = '/'.join(test.path_in_suite[:-1]).replace('.', '_') # class_name = f'{suite_name}.{path or suite_name}' class_name = suite_name + '.' + (path or suite_name) name = test.path_in_suite[-1] time = test.result.elapsed or 0.0 # file.write(f'<testcase classname={quo(class_name)} name={quo(name)} time="{time:.2f}"') file.write( '<testcase classname={class_name} name={name} time="{time:.2f}"'. format(class_name=quo(class_name), name=quo(name), time=time)) if test.isFailure(): file.write('>\n <failure><![CDATA[') # In the unlikely case that the output contains the CDATA # terminator we wrap it by creating a new CDATA block. output = test.result.output.replace(']]>', ']]]]><![CDATA[>') if isinstance(output, bytes): output = output.decode("utf-8", 'ignore') # The Jenkins JUnit XML parser throws an exception if the output # contains control characters like \x1b (e.g. if there is some # -fcolor-diagnostics output). output = escape_control_chars(output) file.write(output) file.write(']]></failure>\n</testcase>\n') elif test.result.code in self.skipped_codes: reason = self._get_skip_reason(test) # file.write(f'>\n <skipped message={quo(reason)}/>\n</testcase>\n') file.write( '>\n <skipped message={reason}/>\n</testcase>\n'.format( reason=quo(reason))) else: file.write('/>\n')
def _write_testsuite(self, file, suite, tests): skipped = sum(1 for t in tests if t.result.code in self.skipped_codes) failures = sum(1 for t in tests if t.isFailure()) name = suite.config.name.replace('.', '-') # file.write(f'<testsuite name={quo(name)} tests="{len(tests)}" failures="{failures}" skipped="{skipped}">\n') file.write('<testsuite name={name} tests="{tests}" failures="{failures}" skipped="{skipped}">\n'.format( name=quo(name), tests=len(tests), failures=failures, skipped=skipped)) for test in tests: self._write_test(file, test, name) file.write('</testsuite>\n')
def _write_test(self, file, test, suite_name): path = '/'.join(test.path_in_suite[:-1]).replace('.', '_') # class_name = f'{suite_name}.{path or suite_name}' class_name = suite_name + '.' + (path or suite_name) name = test.path_in_suite[-1] time = test.result.elapsed or 0.0 # file.write(f'<testcase classname={quo(class_name)} name={quo(name)} time="{time:.2f}"') file.write( '<testcase classname={class_name} name={name} time="{time:.2f}"'. format(class_name=quo(class_name), name=quo(name), time=time)) if test.isFailure(): file.write('>\n <failure><![CDATA[') # In the unlikely case that the output contains the CDATA # terminator we wrap it by creating a new CDATA block. output = test.result.output.replace(']]>', ']]]]><![CDATA[>') if isinstance(output, bytes): output = output.decode("utf-8", 'ignore') # Failing test output sometimes contains control characters like # \x1b (e.g. if there was some -fcolor-diagnostics output) which are # not allowed inside XML files. # This causes problems with CI systems: for example, the Jenkins # JUnit XML will throw an exception when ecountering those # characters and similar problems also occur with GitLab CI. output = remove_invalid_xml_chars(output) file.write(output) file.write(']]></failure>\n</testcase>\n') elif test.result.code in self.skipped_codes: reason = self._get_skip_reason(test) # file.write(f'>\n <skipped message={quo(reason)}/>\n</testcase>\n') file.write( '>\n <skipped message={reason}/>\n</testcase>\n'.format( reason=quo(reason))) else: file.write('/>\n')