xmlunit.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # -*- coding: utf-8 -*-
  2. """
  3. :codeauthor: Pedro Algarvio (pedro@algarvio.me)
  4. :copyright: Copyright 2014 by the SaltStack Team, see AUTHORS for more details.
  5. :license: Apache 2.0, see LICENSE for more details.
  6. tests.support.xmlunit
  7. ~~~~~~~~~~~~~~~~~~~
  8. XML Unit Tests
  9. """
  10. # pylint: disable=wrong-import-order,wrong-import-position
  11. # Import python libs
  12. from __future__ import absolute_import
  13. import io
  14. import logging
  15. log = logging.getLogger(__name__)
  16. try:
  17. import xmlrunner.runner
  18. import xmlrunner.result
  19. HAS_XMLRUNNER = True
  20. class _DuplicateWriter(io.TextIOBase):
  21. """
  22. Duplicate output from the first handle to the second handle
  23. The second handle is expected to be a StringIO and not to block.
  24. """
  25. def __init__(self, first, second):
  26. super(_DuplicateWriter, self).__init__()
  27. self._first = first
  28. self._second = second
  29. def flush(self):
  30. self._first.flush()
  31. self._second.flush()
  32. def writable(self):
  33. return True
  34. def writelines(self, lines):
  35. self._first.writelines(lines)
  36. self._second.writelines(lines)
  37. def write(self, b):
  38. if isinstance(self._first, io.TextIOBase):
  39. wrote = self._first.write(b)
  40. if wrote is not None:
  41. # expected to always succeed to write
  42. self._second.write(b[:wrote])
  43. return wrote
  44. else:
  45. # file-like object in Python2
  46. # It doesn't return wrote bytes.
  47. self._first.write(b)
  48. self._second.write(b)
  49. return len(b)
  50. def fileno(self):
  51. return self._first.fileno()
  52. xmlrunner.result._DuplicateWriter = _DuplicateWriter
  53. class _XMLTestResult(xmlrunner.result._XMLTestResult):
  54. def startTest(self, test):
  55. log.debug(">>>>> START >>>>> %s", test.id())
  56. # xmlrunner classes are NOT new-style classes
  57. xmlrunner.result._XMLTestResult.startTest(self, test)
  58. def stopTest(self, test):
  59. log.debug("<<<<< END <<<<<<< %s", test.id())
  60. # xmlrunner classes are NOT new-style classes
  61. return xmlrunner.result._XMLTestResult.stopTest(self, test)
  62. class XMLTestRunner(xmlrunner.runner.XMLTestRunner):
  63. def _make_result(self):
  64. return _XMLTestResult(
  65. self.stream, self.descriptions, self.verbosity, self.elapsed_times
  66. )
  67. def run(self, test):
  68. result = xmlrunner.runner.XMLTestRunner.run(self, test)
  69. self.stream.writeln("Finished generating XML reports")
  70. return result
  71. except ImportError:
  72. HAS_XMLRUNNER = False
  73. class XMLTestRunner(object):
  74. """
  75. This is a dumb class just so we don't break projects at import time
  76. """