lifecycle.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. from collections import OrderedDict
  2. from contextlib import contextmanager
  3. from allure_commons._core import plugin_manager
  4. from allure_commons.model2 import TestResultContainer
  5. from allure_commons.model2 import TestResult
  6. from allure_commons.model2 import Attachment, ATTACHMENT_PATTERN
  7. from allure_commons.model2 import TestStepResult
  8. from allure_commons.model2 import ExecutableItem
  9. from allure_commons.model2 import TestBeforeResult
  10. from allure_commons.model2 import TestAfterResult
  11. from allure_commons.utils import uuid4
  12. from allure_commons.utils import now
  13. from allure_commons.types import AttachmentType
  14. class AllureLifecycle:
  15. def __init__(self):
  16. self._items = OrderedDict()
  17. def _get_item(self, uuid=None, item_type=None):
  18. uuid = uuid or self._last_item_uuid(item_type=item_type)
  19. return self._items.get(uuid)
  20. def _pop_item(self, uuid=None, item_type=None):
  21. uuid = uuid or self._last_item_uuid(item_type=item_type)
  22. return self._items.pop(uuid, None)
  23. def _last_item_uuid(self, item_type=None):
  24. for uuid in reversed(self._items):
  25. item = self._items.get(uuid)
  26. if item_type is None:
  27. return uuid
  28. elif isinstance(item, item_type):
  29. return uuid
  30. @contextmanager
  31. def schedule_test_case(self, uuid=None):
  32. test_result = TestResult()
  33. test_result.uuid = uuid or uuid4()
  34. self._items[test_result.uuid] = test_result
  35. yield test_result
  36. @contextmanager
  37. def update_test_case(self, uuid=None):
  38. yield self._get_item(uuid=uuid, item_type=TestResult)
  39. def write_test_case(self, uuid=None):
  40. test_result = self._pop_item(uuid=uuid, item_type=TestResult)
  41. if test_result:
  42. plugin_manager.hook.report_result(result=test_result)
  43. @contextmanager
  44. def start_step(self, parent_uuid=None, uuid=None):
  45. parent = self._get_item(uuid=parent_uuid, item_type=ExecutableItem)
  46. step = TestStepResult()
  47. step.start = now()
  48. parent.steps.append(step)
  49. self._items[uuid or uuid4()] = step
  50. yield step
  51. @contextmanager
  52. def update_step(self, uuid=None):
  53. yield self._get_item(uuid=uuid, item_type=TestStepResult)
  54. def stop_step(self, uuid=None):
  55. step = self._pop_item(uuid=uuid, item_type=TestStepResult)
  56. if step and not step.stop:
  57. step.stop = now()
  58. @contextmanager
  59. def start_container(self, uuid=None):
  60. container = TestResultContainer(uuid=uuid or uuid4())
  61. self._items[container.uuid] = container
  62. yield container
  63. def containers(self):
  64. for item in self._items.values():
  65. if isinstance(item, TestResultContainer):
  66. yield item
  67. @contextmanager
  68. def update_container(self, uuid=None):
  69. yield self._get_item(uuid=uuid, item_type=TestResultContainer)
  70. def write_container(self, uuid=None):
  71. container = self._pop_item(uuid=uuid, item_type=TestResultContainer)
  72. if container and (container.befores or container.afters):
  73. plugin_manager.hook.report_container(container=container)
  74. @contextmanager
  75. def start_before_fixture(self, parent_uuid=None, uuid=None):
  76. fixture = TestBeforeResult()
  77. parent = self._get_item(uuid=parent_uuid, item_type=TestResultContainer)
  78. if parent:
  79. parent.befores.append(fixture)
  80. self._items[uuid or uuid4()] = fixture
  81. yield fixture
  82. @contextmanager
  83. def update_before_fixture(self, uuid=None):
  84. yield self._get_item(uuid=uuid, item_type=TestBeforeResult)
  85. def stop_before_fixture(self, uuid=None):
  86. fixture = self._pop_item(uuid=uuid, item_type=TestBeforeResult)
  87. if fixture and not fixture.stop:
  88. fixture.stop = now()
  89. @contextmanager
  90. def start_after_fixture(self, parent_uuid=None, uuid=None):
  91. fixture = TestAfterResult()
  92. parent = self._get_item(uuid=parent_uuid, item_type=TestResultContainer)
  93. if parent:
  94. parent.afters.append(fixture)
  95. self._items[uuid or uuid4()] = fixture
  96. yield fixture
  97. @contextmanager
  98. def update_after_fixture(self, uuid=None):
  99. yield self._get_item(uuid=uuid, item_type=TestAfterResult)
  100. def stop_after_fixture(self, uuid=None):
  101. fixture = self._pop_item(uuid=uuid, item_type=TestAfterResult)
  102. if fixture and not fixture.stop:
  103. fixture.stop = now()
  104. def _attach(self, uuid, name=None, attachment_type=None, extension=None, parent_uuid=None):
  105. mime_type = attachment_type
  106. extension = extension if extension else 'attach'
  107. if type(attachment_type) is AttachmentType:
  108. extension = attachment_type.extension
  109. mime_type = attachment_type.mime_type
  110. file_name = ATTACHMENT_PATTERN.format(prefix=uuid, ext=extension)
  111. attachment = Attachment(source=file_name, name=name, type=mime_type)
  112. last_uuid = parent_uuid if parent_uuid else self._last_item_uuid(ExecutableItem)
  113. self._items[last_uuid].attachments.append(attachment)
  114. return file_name
  115. def attach_file(self, uuid, source, name=None, attachment_type=None, extension=None, parent_uuid=None):
  116. file_name = self._attach(uuid, name=name, attachment_type=attachment_type,
  117. extension=extension, parent_uuid=parent_uuid)
  118. plugin_manager.hook.report_attached_file(source=source, file_name=file_name)
  119. def attach_data(self, uuid, body, name=None, attachment_type=None, extension=None, parent_uuid=None):
  120. file_name = self._attach(uuid, name=name, attachment_type=attachment_type,
  121. extension=extension, parent_uuid=parent_uuid)
  122. plugin_manager.hook.report_attached_data(body=body, file_name=file_name)