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=[]))
예제 #7
0
 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