def test_get_conclusion_parse_errors(self): actual = get_conclusion(ParsedUnitTestResults( files=2, errors=[ParseError(file='file', message='error', line=None, column=None)], suites=1, suite_tests=4, suite_skipped=1, suite_failures=1, suite_errors=1, suite_time=10, cases=[] )) self.assertEqual('failure', actual)
def test_parse_junit_xml_files_with_empty_file(self): self.assertEqual( parse_junit_xml_files(['files/empty.xml']), ParsedUnitTestResults(cases=[], files=1, errors=[ ParseError('files/empty.xml', 'File is empty.', None, None) ], suite_errors=0, suite_failures=0, suite_skipped=0, suite_tests=0, suite_time=0, suites=0))
def test_parse_junit_xml_files_with_non_existing_file(self): self.assertEqual( parse_junit_xml_files(['files/does_not_exist.xml']), ParsedUnitTestResults(cases=[], files=1, errors=[ ParseError('files/does_not_exist.xml', 'File does not exist.', None, None) ], suite_errors=0, suite_failures=0, suite_skipped=0, suite_tests=0, suite_time=0, suites=0))
def test_parse_junit_xml_files_with_non_junit_file(self): self.assertEqual( parse_junit_xml_files(['files/non-junit.xml']), ParsedUnitTestResults(files=1, errors=[ ParseError(file='files/non-junit.xml', message='Invalid format.', line=None, column=None) ], suites=0, suite_tests=0, suite_skipped=0, suite_failures=0, suite_errors=0, suite_time=0, cases=[]))
def test_parse_junit_xml_files_with_corrupt_xml_file(self): self.assertEqual( parse_junit_xml_files(['files/corrupt-xml.xml']), ParsedUnitTestResults( files=1, errors=[ ParseError( file='files/corrupt-xml.xml', message= 'File is not a valid XML file:\nno element found: line 11, column 21', line=11, column=21) ], suites=0, suite_tests=0, suite_skipped=0, suite_failures=0, suite_errors=0, suite_time=0, cases=[]))
def test_parse_junit_xml_files_with_non_xml_file(self): self.assertEqual( parse_junit_xml_files(['files/non-xml.xml']), ParsedUnitTestResults( files=1, errors=[ ParseError( file='files/non-xml.xml', message= 'File is not a valid XML file:\nsyntax error: line 1, column 0', line=1, column=0) ], suites=0, suite_tests=0, suite_skipped=0, suite_failures=0, suite_errors=0, suite_time=0, cases=[]))
def test_get_conclusion_parse_errors(self): for fail_on_errors in [True, False]: for fail_on_failures in [True, False]: with self.subTest(fail_on_errors=fail_on_errors, fail_on_failures=fail_on_failures): actual = get_conclusion(ParsedUnitTestResults( files=2, errors=[ ParseError(file='file', message='error', line=None, column=None) ], suites=1, suite_tests=4, suite_skipped=1, suite_failures=0, suite_errors=0, suite_time=10, cases=[]), fail_on_errors=fail_on_errors, fail_on_failures=fail_on_failures) self.assertEqual( 'failure' if fail_on_errors else 'success', actual)
def parse_junit_xml_files(files: Iterable[str]) -> ParsedUnitTestResults: """Parses junit xml files and returns aggregated statistics as a ParsedUnitTestResults.""" def parse(path: str) -> Union[str, Any]: if not os.path.exists(path): return FileNotFoundError(f'File does not exist.') if os.stat(path).st_size == 0: return Exception(f'File is empty.') try: return JUnitXml.fromfile(path) except BaseException as e: return e parsed_files = [(result_file, parse(result_file)) for result_file in files] junits = [(result_file, junit) for result_file, junit in parsed_files if not isinstance(junit, BaseException)] errors = [ ParseError.from_exception(result_file, exception) for result_file, exception in parsed_files if isinstance(exception, BaseException) ] suites = [(result_file, suite) for result_file, junit in junits for suite in (junit if junit._tag == "testsuites" else [junit])] suite_tests = sum([suite.tests for result_file, suite in suites]) suite_skipped = sum([suite.skipped for result_file, suite in suites]) suite_failures = sum([suite.failures for result_file, suite in suites]) suite_errors = sum([suite.errors for result_file, suite in suites]) suite_time = int(sum([suite.time for result_file, suite in suites])) def int_opt(string: Optional[str]) -> Optional[int]: try: return int(string) if string else None except ValueError: return None cases = [ UnitTestCase(result_file=result_file, test_file=case._elem.get('file'), line=int_opt(case._elem.get('line')), class_name=case.classname, test_name=case.name, result=case.result._tag if case.result else 'success', message=unescape(case.result.message) if case.result and case.result.message is not None else None, content=unescape(case.result._elem.text) if case.result and case.result._elem.text is not None else None, time=case.time) for result_file, suite in suites for case in suite if case.classname is not None and case.name is not None ] return ParsedUnitTestResults( files=len(parsed_files), errors=errors, # test state counts from suites suites=len(suites), suite_tests=suite_tests, suite_skipped=suite_skipped, suite_failures=suite_failures, suite_errors=suite_errors, suite_time=suite_time, # test cases cases=cases)
import unittest import mock from github import Github from github_action import GithubAction from publish import * from publish.publisher import Publisher, Settings from unittestresults import UnitTestCase, ParseError from collections import Collection errors = [ParseError('file', 'error', 1, 2)] class TestPublisher(unittest.TestCase): @staticmethod def create_github_collection(collection: Collection) -> mock.Mock: mocked = mock.MagicMock() mocked.totalCount = len(collection) mocked.__iter__ = mock.Mock(side_effect=collection.__iter__) return mocked @staticmethod def create_github_pr(repo: str, sha: Optional[str] = None, number: Optional[int] = None, state: Optional[str] = None): pr = mock.MagicMock() pr.as_pull_request = mock.Mock(return_value=pr) pr.base.repo.full_name = repo pr.base.sha = sha