Python Library Unittest
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

test.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. import logging
  5. logger = logging.getLogger('__unittest__')
  6. REPORT_LEVEL_FAIL = logging.ERROR
  7. REPORT_LEVEL_INSPECT = logging.WARNING
  8. REPORT_LEVEL_PASS = logging.INFO
  9. def __get_repr__(value, data_filter=repr):
  10. if type(value) == dict:
  11. return '{ ' + ', '.join(['%s: %s' % (repr(key), __get_repr__(value.get(key))) for key in value.keys()]) + ' }'
  12. elif type(value) == list:
  13. return '[ ' + ', '.join(['%s' % (__get_repr__(v)) for v in value]) + ' ]'
  14. else:
  15. return data_filter(value)
  16. def __report_result__(result, description, data_filter=repr):
  17. logger.debug('Result (%s): %s (%s)', description, __get_repr__(result, data_filter), repr(type(result)))
  18. def __report_expectation_equivalency__(expectation, description, data_filter=repr):
  19. logger.debug('Expectation (%s): result = %s (%s)', description, __get_repr__(expectation, data_filter), repr(type(expectation)))
  20. def __report_expectation_range__(min_expectation, max_expectation, description):
  21. logger.debug('Expectation (%s): %s <= result <= %s', description, __get_repr__(min_expectation), __get_repr__(max_expectation))
  22. def __equivalent_dict__(result, expectation, report_comment_fail=None, dict_key='test_variable'):
  23. result_keys = set(result.keys())
  24. expect_keys = set(expectation.keys())
  25. #
  26. log_lvl = REPORT_LEVEL_PASS
  27. #
  28. # missing elements
  29. #
  30. missing_keys = expect_keys - result_keys
  31. if len(missing_keys) > 0:
  32. logger.error('Missing key(s) in dict (%s): %s.' + report_comment_fail, dict_key, ', '.join(['%s' % repr(key) for key in missing_keys]))
  33. log_lvl = REPORT_LEVEL_FAIL
  34. #
  35. # odd elements
  36. #
  37. odd_keys = result_keys - expect_keys
  38. if len(odd_keys) > 0:
  39. logger.error('Odd key(s) in dict (%s): %s.' + report_comment_fail, dict_key, ', '.join(['%s' % repr(key) for key in odd_keys]))
  40. log_lvl = REPORT_LEVEL_FAIL
  41. #
  42. # differences
  43. #
  44. common_keys = result_keys - missing_keys - odd_keys
  45. for key in common_keys:
  46. ll = __equivalent__(result[key], expectation[key], report_comment_fail=report_comment_fail, dict_key=dict_key + ('.' if dict_key != '' else '') + str(key))
  47. if log_lvl < ll:
  48. log_lvl = ll
  49. return log_lvl
  50. def __equivalent_list__(result, expectation, report_comment_fail=None, list_key='test_variable'):
  51. _odd_ = []
  52. _result_ = result[:]
  53. e_index = list(range(0, len(expectation)))
  54. log_lvl = REPORT_LEVEL_PASS
  55. r = 0
  56. while len(_result_) > 0:
  57. value = _result_.pop(0)
  58. just_type_diff = None
  59. for e in e_index:
  60. ll = __equivalent__(value, expectation[e], None)
  61. if ll == REPORT_LEVEL_PASS:
  62. e_index.pop(e_index.index(e))
  63. break
  64. elif ll == REPORT_LEVEL_INSPECT:
  65. just_type_diff = e
  66. else:
  67. if just_type_diff is None:
  68. _odd_.append(value)
  69. else:
  70. log_lvl = __equivalent__(value, expectation[just_type_diff], report_comment_fail, dict_key='%s[%d]' % (list_key, r))
  71. e_index.pop(e_index.index(just_type_diff))
  72. r += 1
  73. #
  74. # missing elements
  75. #
  76. if len(e_index) > 0:
  77. logger.error('Missing value(s) in list (%s): %s.' + report_comment_fail, list_key, ', '.join(['%s' % repr(expectation[e]) for e in e_index]))
  78. log_lvl = REPORT_LEVEL_FAIL
  79. #
  80. # odd elements
  81. #
  82. if len(_odd_) > 0:
  83. logger.error('Odd value(s) in list (%s): %s.' + report_comment_fail, list_key, ', '.join(['%s' % repr(v) for v in _odd_]))
  84. log_lvl = REPORT_LEVEL_FAIL
  85. return log_lvl
  86. def __equivalent__(result, expectation, report_comment_fail=None, dict_key='test_variable'):
  87. report_comment_fail = (' ' + report_comment_fail) if report_comment_fail is not None else ''
  88. log_lvl = REPORT_LEVEL_PASS
  89. if type(result) == dict and type(expectation) == dict:
  90. ll = __equivalent_dict__(result, expectation, report_comment_fail, dict_key)
  91. if log_lvl < ll:
  92. log_lvl = ll
  93. elif type(result) == list and type(expectation) == list:
  94. ll = __equivalent_list__(result, expectation, report_comment_fail, dict_key)
  95. if log_lvl < ll:
  96. log_lvl = ll
  97. else:
  98. if result != expectation:
  99. log_lvl = REPORT_LEVEL_FAIL
  100. logger.error('Content %s is incorrect' + (' for %s' % dict_key if dict_key != '' else '') + '.' + report_comment_fail, __get_repr__(result))
  101. if type(result) != type(expectation):
  102. if log_lvl < REPORT_LEVEL_INSPECT:
  103. log_lvl = REPORT_LEVEL_INSPECT
  104. logger.warning('Type %s is NOT %s%s (%s). ' + report_comment_fail.strip() or '', __get_repr__(type(result)), __get_repr__(type(expectation)), (' for %s' % dict_key if dict_key != '' else ''), __get_repr__(result))
  105. return log_lvl
  106. def equivalency_chk(result, expectation, tcl, description='Variable', report_comment_fail=None, data_filter=repr):
  107. """
  108. Routine to check values for equivalency inside a test run and report to a testCaseLogger.
  109. :param result: The result of a test execution of a module
  110. :type result: All types are supported
  111. :param expectation: The expected value (shall be equivalent to result)
  112. :type expectation: All types are supported
  113. :param description: A descrition of the result. It will be reported like "xxx is correct." Example: descrition="stringrepresentation created by modulename"
  114. :type description: str
  115. :param report_level_pass: The reporting level as defined in :class:`logging` (e.g.: logging.INFO)
  116. :param report_level_fail: The reporting level as defined in :class:`logging` (e.g.: logging.ERROR)
  117. :param report_comment_fail: Comment for a failed Testexecution. Will be added in brakets after the Result-Text.
  118. :type report_comment_fail: str
  119. """
  120. __report_result__(result, description, data_filter=data_filter)
  121. __report_expectation_equivalency__(expectation, description, data_filter=data_filter)
  122. report_level = __equivalent__(result, expectation, report_comment_fail=report_comment_fail, dict_key='result')
  123. if report_level == REPORT_LEVEL_PASS:
  124. tcl.log(report_level, description + ' is correct (Content %s and Type is %s).', data_filter(result), repr(type(result)))
  125. else:
  126. tcl.log(report_level, description + ' is NOT correct. See detailed log for more information.')
  127. return report_level
  128. class equivalency_order_chk(object):
  129. def __init__(self, ordered_values, tcl, description='Variable', report_comment_fail=None):
  130. self._expected_values = ordered_values
  131. self._tcl = tcl
  132. self._description = description
  133. self._report_comment_fail = report_comment_fail
  134. self._reported_values = []
  135. def report_value(self, value):
  136. self._reported_values.append(value)
  137. def report(self):
  138. __report_result__(self._reported_values, self._description)
  139. __report_expectation_equivalency__(self._expected_values, self._description)
  140. report_lvl = REPORT_LEVEL_PASS
  141. for i in range(0, min(len(self._expected_values), len(self._reported_values))):
  142. report_lvl = max(report_lvl, equivalency_chk(self._reported_values[i], self._expected_values[i], logger, 'Submitted value number %d' % (i + 1), self._report_comment_fail))
  143. if report_lvl <= REPORT_LEVEL_PASS:
  144. self._tcl.log(report_lvl, self._description + ': Values and number of submitted values is correct. See detailed log for more information.')
  145. else:
  146. self._tcl.log(report_lvl, self._description + ': Values and number of submitted values is NOT correct. See detailed log for more information.')
  147. return report_lvl
  148. def report_range_check(self, minus_tollerance, plus_tollerance):
  149. __report_result__(self._reported_values, self._description)
  150. report_lvl = REPORT_LEVEL_PASS
  151. report_lvl = max(report_lvl, equivalency_chk(len(self._reported_values), len(self._reported_values), self._tcl, 'Number of submitted values', self._report_comment_fail))
  152. for i in range(0, min(len(self._expected_values), len(self._reported_values))):
  153. report_lvl = max(report_lvl, range_chk(self._reported_values[i], self._expected_values[i] - minus_tollerance, self._expected_values[i] + plus_tollerance, logger, 'Submitted value number %d' % (i + 1), self._report_comment_fail))
  154. if report_lvl <= REPORT_LEVEL_PASS:
  155. self._tcl.log(report_lvl, self._description + ': Valueaccuracy and number of submitted values is correct. See detailed log for more information.')
  156. else:
  157. self._tcl.log(report_lvl, self._description + ': Valueaccuracy and number of submitted values is NOT correct. See detailed log for more information.')
  158. return report_lvl
  159. def __range__(result, min_expectation, max_expectation, report_comment_fail):
  160. report_comment_fail = (' ' + report_comment_fail) if report_comment_fail is not None else ''
  161. log_lvl = REPORT_LEVEL_PASS
  162. if result < min_expectation or result > max_expectation:
  163. log_lvl = REPORT_LEVEL_FAIL
  164. logger.error('Content %s is incorrect.' + report_comment_fail, __get_repr__(result))
  165. if type(result) != type(min_expectation) or type(result) != type(max_expectation):
  166. if log_lvl < REPORT_LEVEL_INSPECT:
  167. log_lvl = REPORT_LEVEL_INSPECT
  168. logger.warning('Type %s is incorrect.' + report_comment_fail, __get_repr__(type(result)))
  169. return log_lvl
  170. def range_chk(result, min_expectation, max_expectation, tcl, description='Value', report_comment_fail=None):
  171. """
  172. Routine to check values to be in a range inside a test run and report to a testCaseLogger.
  173. :param result: The result of a test execution of a module
  174. :type result: All numeric types are supported
  175. :param min: The result shall be more or equal
  176. :type min: All numeric types are supported
  177. :param max: The result shall be less or equivalent
  178. :type max: All numeric types are supported
  179. :param description: A descrition of the result. It will be reported like "xxx is correct." Example: descrition="stringrepresentation created by modulename"
  180. :type description: str
  181. :param report_level_pass: The reporting level as defined in :class:`logging` (e.g.: logging.INFO)
  182. :param report_level_fail: The reporting level as defined in :class:`logging` (e.g.: logging.ERROR)
  183. :param report_comment_fail: Comment for a failed Testexecution. Will be added in brakets after the Result-Text.
  184. :type report_comment_fail: str
  185. """
  186. __report_result__(result, description)
  187. __report_expectation_range__(min_expectation, max_expectation, description)
  188. report_level = __range__(result, min_expectation, max_expectation, report_comment_fail=report_comment_fail)
  189. if report_level == REPORT_LEVEL_PASS:
  190. tcl.log(report_level, description + ' is correct (Content %s in [%s ... %s] and Type is %s).', repr(result), repr(min_expectation), repr(max_expectation), repr(type(result)))
  191. else:
  192. tcl.log(report_level, description + ' is NOT correct. See detailed log for more information.')
  193. return report_level
  194. def in_list_chk(result, expectation_list, tcl, description='Value', report_level_pass=logging.INFO, report_level_fail=logging.ERROR, report_comment_fail=None):
  195. """
  196. Routine to check values to be in a range inside a test run and report to a testCaseLogger.
  197. :param result: The result of a test execution of a module
  198. :type result: All types are supported
  199. :param expectation_list: The list of allowed values
  200. :type expectation_list: A list of all types is supported
  201. :param description: A descrition of the result. It will be reported like "xxx is correct." Example: descrition="stringrepresentation created by modulename"
  202. :type description: str
  203. :param report_level_pass: The reporting level as defined in :class:`logging` (e.g.: logging.INFO)
  204. :param report_level_fail: The reporting level as defined in :class:`logging` (e.g.: logging.ERROR)
  205. :param report_comment_fail: Comment for a failed Testexecution. Will be added in brakets after the Result-Text.
  206. :type report_comment_fail: str
  207. """
  208. __report_values__(result, expectation)
  209. tcl.log(REPORT_LEVEL_FAIL, 'in_list check not yet implemented')
  210. return REPORT_LEVEL_FAIL