Coverage for genbadge/utils_junit.py: 73%

49 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-11-10 20:37 +0000

1# Authors: Sylvain MARIE <sylvain.marie@se.com> 

2# + All contributors to <https://github.com/smarie/python-genbadge> 

3# 

4# License: 3-clause BSD, <https://github.com/smarie/python-genbadge/blob/master/LICENSE> 

5from __future__ import division 

6 

7from io import TextIOWrapper 

8 

9try: 

10 from typing import Union 

11except ImportError: 

12 pass 

13 

14# use our own copy so as to use defusedxml and to be compliant with setuptools>=58 

15from .xunitparser_copy import parse 

16from .utils_badge import Badge 

17 

18 

19class TestStats(object): 

20 """ 

21 Contains the results from parsing the Junit style test report (junit.xml). 

22 Some stats are available as properties, computed based on others. 

23 """ 

24 def __init__(self, runned, skipped, failed, errors): 

25 self.runned = runned 

26 self.failed = failed 

27 self.skipped = skipped 

28 self.errors = errors 

29 

30 @property 

31 def success(self): 

32 return self.runned - self.skipped - self.failed 

33 

34 @property 

35 def total_with_skipped(self): 

36 return self.runned + self.errors 

37 

38 @property 

39 def total_without_skipped(self): 

40 return self.runned - self.skipped + self.errors 

41 

42 @property 

43 def success_percentage(self): 

44 if self.runned > 0: 44 ↛ 47line 44 didn't jump to line 47, because the condition on line 44 was never false

45 return self.success * 100 / self.total_without_skipped 

46 else: 

47 return 100 

48 

49 def __repr__(self): 

50 return "%s(%s)" % (self.__class__.__name__, ",".join("%s=%r" % (k, v) for k, v in vars(self).items())) 

51 

52 

53def get_test_stats(junit_xml_file='reports/junit/junit.xml' # type: Union[str, TextIOWrapper] 

54 ): 

55 # type: (...) -> TestStats 

56 """ 

57 read the junit test file and extract the success percentage 

58 :param junit_xml_file: the junit xml file path or file/text stream 

59 :return: the success percentage (an int) 

60 """ 

61 if isinstance(junit_xml_file, str): 

62 # assume a file path 

63 with open(junit_xml_file) as f: 

64 ts, tr = parse(f) 

65 else: 

66 # assume a stream already 

67 ts, tr = parse(junit_xml_file) 

68 

69 runned = tr.testsRun 

70 skipped = len(tr.skipped) 

71 failed = len(tr.failures) 

72 errors = len(tr.errors) 

73 

74 return TestStats(runned=runned, skipped=skipped, failed=failed, errors=errors) 

75 

76 

77def get_color( 

78 test_stats # type: TestStats 

79): 

80 """ Returns the badge color to use depending on the success percentage """ 

81 

82 if test_stats.success_percentage < 50: 82 ↛ 84line 82 didn't jump to line 84, because the condition on line 82 was never false

83 color = 'red' 

84 elif test_stats.success_percentage < 75: 

85 color = 'orange' 

86 elif test_stats.success_percentage < 90: 

87 color = 'green' 

88 else: 

89 color = 'brightgreen' 

90 

91 return color 

92 

93 

94def get_tests_badge( 

95 test_stats, # type: TestStats 

96 left_txt = "tests" # type: str 

97): 

98 # type: (...) -> Badge 

99 """Return the badge from test statistics """ 

100 

101 color = get_color(test_stats) 

102 

103 if test_stats.success_percentage < 100: 103 ↛ 108line 103 didn't jump to line 108, because the condition on line 103 was never false

104 # full badge 

105 right_txt = "%s/%s" % (test_stats.success, test_stats.total_without_skipped) 

106 else: 

107 # simplified badge showing the number of tests 

108 right_txt = "%s" % (test_stats.total_without_skipped,) 

109 

110 return Badge(left_txt=left_txt, right_txt=right_txt, color=color)