示例#1
0
 def __init__(self, behave_config):
     self.behave_config = behave_config
     self.logger = AllureReporter()
     self.current_step_uuid = None
     self.execution_context = Context()
     self.fixture_context = Context()
     self.steps = deque()
 def __init__(self, default_test_suite_name=None, default_parent_test_suite_name=None, default_sub_suite_name=None):
     self.allure_logger = AllureReporter()
     self._cache = ItemCache()
     self.default_test_suite_name = default_test_suite_name
     self.default_parent_test_suite_name = default_parent_test_suite_name
     self.default_sub_suite_name = default_sub_suite_name
     self.container_uuid=str(uuid4())
     self.current_testcase_container_uuid = None
     self.parent_test_listener = None
示例#3
0
 def __init__(self, logger_path=DEFAULT_OUTPUT_PATH):
     self.reporter = AllureReporter()
     self.logger = AllureFileLogger(logger_path)
     self.stack = []
     self.items_log = {}
     self.pool_id = None
     self.links = OrderedDict()
     plugin_manager.register(self.reporter)
     plugin_manager.register(self.logger)
示例#4
0
    def __init__(self, result_dir):
        self.logger = AllureReporter()
        file_logger = AllureFileLogger(result_dir)
        register(file_logger)

        self.current_group_uuid = None
        self.current_before_uuid = None
        self.current_scenario_uuid = None
        self.current_step_uuid = None
示例#5
0
 def __init__(self, behave_config):
     self.behave_config = behave_config
     self.issue_pattern = behave_config.userdata.get(
         'AllureFormatter.issue_pattern', None)
     self.link_pattern = behave_config.userdata.get(
         'AllureFormatter.link_pattern', None)
     self.logger = AllureReporter()
     self.current_step_uuid = None
     self.current_scenario_uuid = None
     self.execution_context = Context()
     self.fixture_context = Context()
     self.steps = deque()
    def __init__(self, logger_path=DEFAULT_OUTPUT_PATH):
        self.stack = []
        self.items_log = {}
        self.pool_id = None
        self.links = OrderedDict()
        self._previous_keyword_failed = False
        self._traceback_message = None

        self.reporter = AllureReporter()
        self.listener = AllureListener(self.reporter)
        self.logger = AllureFileLogger(logger_path)

        allure_commons.plugin_manager.register(self.logger)
        allure_commons.plugin_manager.register(self.listener)
示例#7
0
 def __init__(self, behave_config):
     self.behave_config = behave_config
     self.issue_pattern = behave_config.userdata.get(
         'AllureFormatter.issue_pattern', None)
     self.link_pattern = behave_config.userdata.get(
         'AllureFormatter.link_pattern', None)
     self.hide_excluded = behave_config.userdata.get(
         'AllureFormatter.hide_excluded', False)
     self.logger = AllureReporter()
     self.current_step_uuid = None
     self.current_scenario_uuid = None
     self.group_context = GroupContext(self.logger)
     self.group_context.enter()
     self.steps = deque()
示例#8
0
class AllureBehaveListener(object):
    def __init__(self):
        self.allure_lifecycle = AllureReporter()

    def before_scenario(self, _, scenario):
        uuid = scenario_history_id(scenario)

        test_case = TestResult(uuid=uuid, start=now())
        test_case.name = scenario_name(scenario)
        test_case.historyId = scenario_history_id(scenario)

        self.allure_lifecycle.schedule_test(uuid, test_case)

    def after_scenario(self, _, scenario):
        uuid = scenario_history_id(scenario)
        self.allure_lifecycle.close_test(uuid)
示例#9
0
def before_all(context):
    if not os.path.exists(LOG_DIR):
        os.makedirs(LOG_DIR)
    report_dir_name = ALLURE_REPORT_DIR
    context.allure = AllureReporter()
    file_logger = AllureFileLogger(report_dir_name)
    allure_commons.plugin_manager.register(file_logger)
示例#10
0
 def __init__(self, behave_config):
     self.behave_config = behave_config
     self.logger = AllureReporter()
     self.current_step_uuid = None
     self.current_scenario_uuid = None
     self.execution_context = Context()
     self.fixture_context = Context()
     self.steps = deque()
 def __init__(self):
     report_root_path = os.path.join(os.getcwd(), "reportsxxxx")
     report_dir_path = os.path.join(
         report_root_path,
         datetime.now().strftime('%Y-%m-%d-%H-%M-%S'))
     if not os.path.isdir(report_dir_path):
         os.makedirs(report_dir_path)
     for f in os.listdir(report_dir_path):
         f = os.path.join(report_dir_path, f)
         if os.path.isfile(f):
             os.unlink(f)
         elif os.path.isdir(f):
             shutil.rmtree(f)
     self.file_logger = AllureFileLogger(report_dir_path)
     allure_commons.plugin_manager.register(self.file_logger)
     self.allure_logger = AllureReporter()
     self.start_at = time.time()
    def __init__(self, logger_path=DEFAULT_OUTPUT_PATH):
        self.stack = []
        self.items_log = {}
        self.pool_id = None
        self.links = OrderedDict()
        self._previous_keyword_failed = False
        self._traceback_message = None

        self.reporter = AllureReporter()
        self.listener = AllureListener(self.reporter)
        self.logger = AllureFileLogger(logger_path)

        allure_commons.plugin_manager.register(self.logger)
        allure_commons.plugin_manager.register(self.listener)
示例#13
0
class AllureCustomListener(AllureListener):
    def __init__(self, behave_config):
        super()
        self.behave_config = behave_config
        self.logger = AllureReporter()
        self.current_step_uuid = None
        self.execution_context = Context()
        self.fixture_context = Context()
        self.steps = deque()
        self.browser = behave_config.userdata['browser']

    @allure_commons.hookimpl
    def start_test(self, parent_uuid, uuid, name, parameters, context):
        scenario = context['scenario']
        self.fixture_context.enter()
        self.execution_context.enter()
        self.execution_context.append(uuid)
        test_case = TestResult(uuid=uuid, start=now())
        test_case.name = scenario_name(scenario)
        test_case.historyId = scenario_history_id(scenario, self.browser)
        test_case.description = '\n'.join(scenario.description)
        test_case.parameters = scenario_parameters(scenario, self.browser)
        test_case.labels.extend([
            Label(name=LabelType.TAG, value=tag)
            for tag in scenario_tags(scenario)
        ])
        test_case.labels.append(
            Label(name=LabelType.SEVERITY,
                  value=scenario_severity(scenario).value))
        test_case.labels.append(
            Label(name=LabelType.FEATURE, value=scenario.feature.name))
        test_case.labels.append(Label(name=LabelType.FRAMEWORK,
                                      value='behave'))
        test_case.labels.append(
            Label(name=LabelType.LANGUAGE, value=platform_label()))
        self.logger.schedule_test(uuid, test_case)
示例#14
0
class AllureListener:
    """allure plugin implementation"""

    def __init__(self, default_test_suite_name=None, default_parent_test_suite_name=None, default_sub_suite_name=None):
        self.allure_logger = AllureReporter()
        self._cache = ItemCache()
        self.default_test_suite_name = default_test_suite_name
        self.default_parent_test_suite_name = default_parent_test_suite_name
        self.default_sub_suite_name = default_sub_suite_name
        self.container_uuid=str(uuid4())
        self.current_testcase_container_uuid = None
        self.parent_test_listener = None

    @allure_commons.hookimpl
    def attach_data(self, body, name, attachment_type, extension):
        """attach data to allure report"""
        self.allure_logger.attach_data(
            uuid4(),
            body,
            name=name,
            attachment_type=attachment_type,
            extension=extension,
        )

    @allure_commons.hookimpl
    def attach_file(self, source, name, attachment_type, extension):
        """attach file to allure report"""
        self.allure_logger.attach_file(
            uuid4(),
            source,
            name=name,
            attachment_type=attachment_type,
            extension=extension,
        )

    @allure_commons.hookimpl
    def add_title(self, test_title):
        """add title to current allure report item"""
        test_result = self.allure_logger.get_test(None)
        if test_result:
            test_result.name = test_title

    @allure_commons.hookimpl
    def add_description(self, test_description):
        """add description to current allure report item"""
        test_result = self.allure_logger.get_test(None)
        if test_result:
            test_result.description = test_description

    @allure_commons.hookimpl
    def start_step(self, uuid, title, params):
        """start step"""
        step_data = StepData()
        self._cache.push(step_data, uuid)
        parameters = [Parameter(name=name, value=value) for name, value in params.items()]
        step = TestStepResult(name=title, start=now(), parameters=parameters)
        self.allure_logger.start_step(None, uuid, step)

    @allure_commons.hookimpl
    def stop_step(self, uuid, exc_type, exc_val, exc_tb):
        """stop step"""
        step_data = self._cache.get(uuid)
        out = sys.stdout.getvalue()
        sys.stdout.close()
        if len(out) != 0:
            self.attach_data(out, "STDOUT", AttachmentType.TEXT, "txt")
        sys.stdout = step_data.prev_stdout
        err = sys.stderr.getvalue()
        sys.stderr.close()
        if len(err) != 0:
            self.attach_data(err, "STDERR", AttachmentType.TEXT, "txt")
        sys.stderr = step_data.prev_stderr
        self.allure_logger.stop_step(
            uuid,
            stop=now(),
            status=get_status(exc_val),
            statusDetails=get_status_details(exc_type, exc_val, exc_tb),
        )

    @allure_commons.hookimpl
    def start_test(self, name, uuid, context):
        """start test"""
        test_result = TestResult(name=name, uuid=uuid, start=now(), stop=now())
        test_result.status = context.status
        if self.default_test_suite_name:
            test_result.labels.append(Label(name=LabelType.SUITE, value=self.default_test_suite_name))
        if self.default_parent_test_suite_name:
            test_result.labels.append(Label(name=LabelType.PARENT_SUITE, value=self.default_parent_test_suite_name))
        if self.default_sub_suite_name:
            test_result.labels.append(Label(name=LabelType.SUB_SUITE, value=self.default_sub_suite_name))
        test_result.labels.append(Label(name=LabelType.FRAMEWORK, value="ArangoDB Release Test Automation"))
        self.allure_logger.schedule_test(uuid, test_result)
        self._cache.push(test_result, uuid)
        for label in context.labels:
            test_result.labels.append(label)
        self.allure_logger.update_group(self.container_uuid, children=uuid)
        parent = self.parent_test_listener
        while parent:
            parent.allure_logger.update_group(parent.container_uuid, children=uuid)
            parent = parent.parent_test_listener
        self.current_testcase_container_uuid = str(uuid4())
        container = TestResultContainer(uuid=self.current_testcase_container_uuid, name=name)
        self._cache.push(container, self.current_testcase_container_uuid)
        self.allure_logger.start_group(self.current_testcase_container_uuid, container)
        self.allure_logger.update_group(self.current_testcase_container_uuid, start=now())
        self.allure_logger.update_group(self.current_testcase_container_uuid, children=uuid)


    # pylint: disable=too-many-arguments
    @allure_commons.hookimpl
    def stop_test(self, uuid, context, exc_type, exc_val, exc_tb):
        """stop test"""
        test_result = self._cache.get(uuid)
        test_result.status = context.status
        if context.statusDetails:
            test_result.statusDetails = context.statusDetails
        test_result.stop = now()
        if exc_type or exc_val or exc_tb:
            test_result.status = get_status(exc_val)
            test_result.statusDetails = get_status_details(exc_type, exc_val, exc_tb)
        for step in test_result.steps:
            if step.status == Status.FAILED:
                test_result.status = Status.FAILED
                test_result.statusDetails = step.statusDetails

        for label in context.labels:
            if label not in test_result.labels:
                test_result.labels.append(label)
        self.allure_logger.close_test(uuid)
        self.allure_logger.stop_group(self.current_testcase_container_uuid)
        self.current_testcase_container_uuid = None

    def start_suite_container(self, suite_name):
        """start a test suite"""
        container = TestResultContainer(uuid=self.container_uuid, name=suite_name)
        self._cache.push(container, self.container_uuid)
        self.allure_logger.start_group(self.container_uuid, container)
        self.allure_logger.update_group(self.container_uuid, start=now())

    def stop_suite_container(self):
        """stop running test suite"""
        self.allure_logger.stop_group(self.container_uuid)

    def start_before_fixture(self, uuid, name):
        """start a fixture that is ran before a test case or test suite"""
        container_uuid = self.current_testcase_container_uuid if self.current_testcase_container_uuid else self.container_uuid
        fixture = TestBeforeResult(name=name, start=now(), parameters={})
        self.allure_logger.start_before_fixture(container_uuid, uuid, fixture)

    def stop_before_fixture(self, uuid, exc_type, exc_val, exc_tb):
        """stop a fixture that is ran before a test case or test suite"""
        self.allure_logger.stop_before_fixture(uuid=uuid,
                                        stop=now(),
                                        status=get_status(exc_val),
                                        statusDetails=get_status_details(exc_type, exc_val, exc_tb))

    def start_after_fixture(self, uuid, name):
        """start a fixture that is ran after a test case or test suite"""
        container_uuid = self.current_testcase_container_uuid if self.current_testcase_container_uuid else self.container_uuid
        fixture = TestAfterResult(name=name, start=now(), parameters={})
        self.allure_logger.start_after_fixture(container_uuid, uuid, fixture)

    def stop_after_fixture(self, uuid, exc_type, exc_val, exc_tb):
        """stop a fixture that is ran after a test case or test suite"""
        self.allure_logger.stop_after_fixture(uuid=uuid,
                                        stop=now(),
                                        status=get_status(exc_val),
                                        statusDetails=get_status_details(exc_type, exc_val, exc_tb))
class allure_robotframework(object):
    ROBOT_LISTENER_API_VERSION = 2
    DEFAULT_OUTPUT_PATH = os.path.join('output', 'allure')
    LOG_MESSAGE_FORMAT = '{full_message}<p><b>[{level}]</b> {message}</p>'
    FAIL_MESSAGE_FORMAT = '{full_message}<p style="color: red"><b>[{level}]</b> {message}</p>'

    def __init__(self, logger_path=DEFAULT_OUTPUT_PATH):
        self.stack = []
        self.items_log = {}
        self.pool_id = None
        self.links = OrderedDict()
        self._previous_keyword_failed = False
        self._traceback_message = None

        self.reporter = AllureReporter()
        self.listener = AllureListener(self.reporter)
        self.logger = AllureFileLogger(logger_path)

        allure_commons.plugin_manager.register(self.logger)
        allure_commons.plugin_manager.register(self.listener)

    def start_suite(self, name, attributes):
        if not self.pool_id:
            self.pool_id = BuiltIn().get_variable_value(
                '${PABOTEXECUTIONPOOLID}')
            self.pool_id = int(self.pool_id) if self.pool_id else 0
        self.start_new_group(name, attributes)

    def end_suite(self, name, attributes):
        self.stop_current_group()

    def start_test(self, name, attributes):
        self.start_new_group(name, attributes)
        self.start_new_test(name, attributes)

    def end_test(self, name, attributes):
        self.stop_current_test(name, attributes)
        self.stop_current_group()

    def start_keyword(self, name, attributes):
        self.start_new_keyword(name, attributes)

    def end_keyword(self, name, attributes):
        self.end_current_keyword(name, attributes)

    def log_message(self, message):
        level = message.get('level')
        if self._previous_keyword_failed:
            self._traceback_message = message.get('message')
            self._previous_keyword_failed = False
        if level == RobotLogLevel.FAIL:
            self._previous_keyword_failed = True
            self.reporter.get_item(
                self.stack[-1]).statusDetails = StatusDetails(
                    message=message.get('message'))
        self.append_message_to_last_item_log(message, level)

    def start_new_group(self, name, attributes):
        uuid = uuid4()
        self.set_suite_link(attributes.get('metadata'), uuid)
        if self.stack:
            parent_suite = self.reporter.get_last_item(TestResultContainer)
            parent_suite.children.append(uuid)
        self.stack.append(uuid)
        suite = TestResultContainer(uuid=uuid,
                                    name=name,
                                    description=attributes.get('doc'),
                                    start=now())
        self.reporter.start_group(uuid, suite)

    def stop_current_group(self):
        uuid = self.stack.pop()
        self.remove_suite_link(uuid)
        self.reporter.stop_group(uuid, stop=now())

    def start_new_test(self, name, attributes):
        uuid = uuid4()
        self.reporter.get_last_item(TestResultContainer).children.append(uuid)
        self.stack.append(uuid)
        test_case = TestResult(uuid=uuid,
                               historyId=md5(attributes.get('longname')),
                               name=name,
                               fullName=attributes.get('longname'),
                               start=now())
        self.reporter.schedule_test(uuid, test_case)

    def stop_current_test(self, name, attributes):
        uuid = self.stack.pop()
        test = self.reporter.get_test(uuid)
        test.status = utils.get_allure_status(attributes.get('status'))
        test.labels.extend(utils.get_allure_suites(attributes.get('longname')))

        test.labels.extend(allure_tags(attributes))
        for label_type in (LabelType.EPIC, LabelType.FEATURE, LabelType.STORY):
            test.labels.extend(allure_labels(attributes, label_type))
        for link_type in (LinkType.ISSUE, LinkType.TEST_CASE, LinkType.LINK):
            test.links.extend(allure_links(attributes, link_type))
        test.labels.append(Label(name=LabelType.THREAD, value=self.pool_id))
        test.labels.append(Label(name=LabelType.HOST, value=host_tag()))
        test.labels.append(
            Label(name=LabelType.FRAMEWORK, value='robotframework'))
        test.labels.append(
            Label(name=LabelType.LANGUAGE, value=platform_label()))
        test.statusDetails = StatusDetails(message=attributes.get('message'),
                                           trace=self.get_traceback_message())
        test.description = attributes.get('doc')
        last_link = list(self.links.values())[-1] if self.links else None
        if attributes.get(Severity.CRITICAL, 'no') == 'yes':
            test.labels.append(
                Label(name=LabelType.SEVERITY, value=Severity.CRITICAL))
        if last_link:
            test.links.append(Link(LinkType.LINK, last_link, 'Link'))
        test.stop = now()
        self.reporter.close_test(uuid)

    def start_new_keyword(self, name, attributes):
        uuid = uuid4()
        parent_uuid = self.stack[-1]
        step_name = '{} = {}'.format(
            attributes.get('assign')[0],
            name) if attributes.get('assign') else name
        args = {
            'name': step_name,
            'description': attributes.get('doc'),
            'parameters': utils.get_allure_parameters(attributes.get('args')),
            'start': now()
        }
        keyword_type = attributes.get('type')
        last_item = self.reporter.get_last_item()
        if keyword_type in RobotKeywordType.FIXTURES and not isinstance(
                last_item, TestStepResult):
            if isinstance(last_item, TestResult):
                parent_uuid = self.stack[-2]
            if keyword_type == RobotKeywordType.SETUP:
                self.reporter.start_before_fixture(parent_uuid, uuid,
                                                   TestBeforeResult(**args))
            elif keyword_type == RobotKeywordType.TEARDOWN:
                self.reporter.start_after_fixture(parent_uuid, uuid,
                                                  TestAfterResult(**args))
            self.stack.append(uuid)
            return
        self.stack.append(uuid)
        self.reporter.start_step(parent_uuid=parent_uuid,
                                 uuid=uuid,
                                 step=TestStepResult(**args))

    def end_current_keyword(self, name, attributes):
        uuid = self.stack.pop()
        if uuid in self.items_log:
            self.reporter.attach_data(uuid=uuid4(),
                                      body=self.items_log.pop(uuid).replace(
                                          '\n', '<br>'),
                                      name='Keyword Log',
                                      attachment_type=AttachmentType.HTML)
        args = {
            'uuid': uuid,
            'status': utils.get_allure_status(attributes.get('status')),
            'stop': now()
        }
        keyword_type = attributes.get('type')
        parent_item = self.reporter.get_last_item()
        if keyword_type in RobotKeywordType.FIXTURES and not isinstance(
                parent_item, TestStepResult):
            if keyword_type == RobotKeywordType.SETUP:
                self.reporter.stop_before_fixture(**args)
                return
            elif keyword_type == RobotKeywordType.TEARDOWN:
                self.reporter.stop_after_fixture(**args)
                return
        self.reporter.stop_step(**args)

    def append_message_to_last_item_log(self, message, level):
        full_message = self.items_log[
            self.stack[-1]] if self.stack[-1] in self.items_log else ''
        message_format = self.FAIL_MESSAGE_FORMAT if level in RobotLogLevel.CRITICAL_LEVELS else self.LOG_MESSAGE_FORMAT
        self.items_log[self.stack[-1]] = message_format.format(
            full_message=full_message,
            level=message.get('level'),
            message=message.get('message'))

    def set_suite_link(self, metadata, uuid):
        if metadata:
            link = metadata.get('Link')
            if link:
                self.links[uuid] = link

    def remove_suite_link(self, uuid):
        if self.links.get(uuid):
            self.links.pop(uuid)

    def get_traceback_message(self):
        if BuiltIn().get_variable_value('${LOG LEVEL}') in (
                RobotLogLevel.DEBUG, RobotLogLevel.TRACE):
            return self._traceback_message
        return None

    def close(self):
        for plugin in [self.logger, self.listener]:
            name = allure_commons.plugin_manager.get_name(plugin)
            allure_commons.plugin_manager.unregister(name=name)
示例#16
0
class AllureListener(object):
    def __init__(self, result_dir):
        self.logger = AllureReporter()
        file_logger = AllureFileLogger(result_dir)
        plugin_manager.register(file_logger)
        plugin_manager.register(self)

        self.current_group_uuid = None
        self.current_before_uuid = None
        self.current_scenario_uuid = None
        self.current_step_uuid = None

    def start_group(self):
        self.current_group_uuid = uuid4()
        group = TestResultContainer(uuid=self.current_group_uuid,
                                    name='Background')
        self.logger.start_group(self.current_group_uuid, group)

    def stop_group(self):
        if self.current_group_uuid:
            self.logger.stop_group(self.current_group_uuid)
            self.current_group_uuid = None

    def update_group(self):
        if self.current_group_uuid:
            self.logger.update_group(self.current_group_uuid,
                                     children=self.current_scenario_uuid)

    def start_before(self, _, background):
        self.current_before_uuid = uuid4()
        before = TestBeforeResult(name=background.name or 'Background')
        self.logger.start_before_fixture(self.current_group_uuid,
                                         self.current_before_uuid, before)

    def stop_before(self, scenario, _):
        status = background_status(scenario)
        self.logger.stop_before_fixture(uuid=self.current_before_uuid,
                                        status=status)
        self.current_before_uuid = None

    def start_scenario(self, scenario):
        self.current_scenario_uuid = uuid4()
        test_case = TestResult(uuid=self.current_scenario_uuid, start=now())

        test_case.name = scenario_name(scenario)
        test_case.historyId = scenario_history_id(scenario)
        test_case.description = '\n'.join(scenario.description)

        labels = []
        feature_label = Label(name=LabelType.FEATURE.value,
                              value=scenario.feature.name)
        severity = (Label(name=LabelType.SEVERITY.value,
                          value=scenario_severity(scenario).value))
        labels.append(feature_label)
        labels.append(severity)
        labels += [
            Label(name=LabelType.TAG.value, value=tag)
            for tag in scenario_tags(scenario)
        ]

        test_case.parameters = scenario_parameters(scenario)
        test_case.labels = labels

        self.logger.schedule_test(self.current_scenario_uuid, test_case)
        self.update_group()

    def stop_scenario(self, scenario):
        status = scenario_status(scenario)
        status_details = scenario_status_details(scenario)
        self.logger.update_test(self.current_scenario_uuid,
                                stop=now(),
                                status=status,
                                statusDetails=status_details)
        self.logger.close_test(self.current_scenario_uuid)
        self.current_scenario_uuid = None
        self.current_step_uuid = None

    def start_step(self, step):
        self.current_step_uuid = uuid4()
        name = u'{keyword} {title}'.format(keyword=step.keyword,
                                           title=step.name)
        parent_uuid = self.current_before_uuid or self.current_scenario_uuid
        allure_step = TestStepResult(name=name, start=now())

        self.logger.start_step(parent_uuid, self.current_step_uuid,
                               allure_step)

        if step.text:
            self.logger.attach_data(uuid4(),
                                    step.text,
                                    name='.text',
                                    attachment_type=AttachmentType.TEXT)
        if step.table:
            table = [','.join(step.table.headings)]
            [table.append(','.join(list(row))) for row in step.table.rows]
            self.logger.attach_data(uuid4(),
                                    '\n'.join(table),
                                    name='.table',
                                    attachment_type=AttachmentType.CSV)

    def stop_step(self, result):
        status = step_status(result)
        status_details = step_status_details(result)
        self.logger.stop_step(self.current_step_uuid,
                              stop=now(),
                              status=status,
                              statusDetails=status_details)

    @hookimpl
    def attach_data(self, body, name, attachment_type, extension):
        self.logger.attach_data(uuid4(),
                                body,
                                name=name,
                                attachment_type=attachment_type,
                                extension=extension)

    @hookimpl
    def attach_file(self, source, name, attachment_type, extension):
        self.logger.attach_file(uuid4(),
                                source,
                                name=name,
                                attachment_type=attachment_type,
                                extension=extension)
示例#17
0
class AllureListener(object):
    def __init__(self, behave_config):
        self.behave_config = behave_config
        self.logger = AllureReporter()
        self.current_step_uuid = None
        self.current_scenario_uuid = None
        self.execution_context = Context()
        self.fixture_context = Context()
        self.steps = deque()

    def __del__(self):
        for group in self.fixture_context.exit():
            group.children.extend(self.execution_context)
            self.logger.stop_group(group.uuid)

    @allure_commons.hookimpl
    def start_fixture(self, parent_uuid, uuid, name, parameters):
        parameters = [
            Parameter(name=param_name, value=param_value)
            for param_name, param_value in parameters.items()
        ]

        if name in FIXTURES and not self.fixture_context:
            group = TestResultContainer(uuid=uuid4())
            self.logger.start_group(group.uuid, group)
            self.fixture_context.append(group)

        if name in BEFORE_FIXTURES:
            fixture = TestBeforeResult(name=name,
                                       start=now(),
                                       parameters=parameters)
            for group in self.fixture_context:
                self.logger.start_before_fixture(group.uuid, uuid, fixture)

        elif name in AFTER_FIXTURES:
            fixture = TestAfterResult(name=name,
                                      start=now(),
                                      parameters=parameters)
            for group in self.fixture_context:
                self.logger.start_after_fixture(group.uuid, uuid, fixture)

    @allure_commons.hookimpl
    def stop_fixture(self, parent_uuid, uuid, name, exc_type, exc_val, exc_tb):
        if name in FIXTURES:
            self.logger.stop_before_fixture(uuid=uuid,
                                            stop=now(),
                                            status=get_status(exc_val),
                                            statusDetails=get_status_details(
                                                exc_type, exc_val, exc_tb))

    def start_feature(self):
        self.execution_context.enter()
        self.fixture_context.enter()

    def stop_feature(self):
        uuids = self.execution_context.exit()
        for group in self.fixture_context.exit():
            group.children.extend(uuids)
            self.logger.stop_group(group.uuid)
        self.execution_context.extend(uuids)

    @allure_commons.hookimpl
    def start_test(self, parent_uuid, uuid, name, parameters, context):
        self.start_scenario(context['scenario'])

    def start_scenario(self, scenario):
        self.current_scenario_uuid = uuid4()
        self.fixture_context.enter()
        self.execution_context.enter()
        self.execution_context.append(self.current_scenario_uuid)

        test_case = TestResult(uuid=self.current_scenario_uuid, start=now())
        test_case.name = scenario_name(scenario)
        test_case.historyId = scenario_history_id(scenario)
        test_case.description = '\n'.join(scenario.description)
        test_case.parameters = scenario_parameters(scenario)

        test_case.links.extend(scenario_links(scenario))
        test_case.labels.extend(scenario_labels(scenario))
        test_case.labels.append(
            Label(name=LabelType.FEATURE, value=scenario.feature.name))
        test_case.labels.append(Label(name=LabelType.FRAMEWORK,
                                      value='behave'))
        test_case.labels.append(
            Label(name=LabelType.LANGUAGE, value=platform_label()))

        self.logger.schedule_test(self.current_scenario_uuid, test_case)

    @allure_commons.hookimpl
    def stop_test(self, parent_uuid, uuid, name, context, exc_type, exc_val,
                  exc_tb):
        self.stop_scenario(context['scenario'])

    def stop_scenario(self, scenario):
        if scenario.status == 'skipped' and not self.behave_config.show_skipped:
            self.logger.drop_test(self.current_scenario_uuid)
        else:
            status = scenario_status(scenario)
            status_details = scenario_status_details(scenario)

            self.flush_steps()
            test_result = self.logger.get_test(self.current_scenario_uuid)
            test_result.stop = now()
            test_result.status = status
            test_result.statusDetails = status_details
            self.logger.close_test(self.current_scenario_uuid)
            self.current_step_uuid = None

            for group in self.fixture_context.exit():
                group.children.append(self.current_scenario_uuid)
                self.logger.stop_group(group.uuid)

        self.execution_context.exit()
        self.execution_context.append(self.current_scenario_uuid)
        self.current_scenario_uuid = None

    def schedule_step(self, step):
        self.steps.append(step)

    def match_step(self, match):
        step = self.steps.popleft()
        self.start_behave_step(step)

    def start_behave_step(self, step):

        self.current_step_uuid = uuid4()
        name = u'{keyword} {title}'.format(keyword=step.keyword,
                                           title=step.name)

        allure_step = TestStepResult(name=name, start=now())
        self.logger.start_step(None, self.current_step_uuid, allure_step)

        if step.text:
            self.logger.attach_data(uuid4(),
                                    step.text,
                                    name='.text',
                                    attachment_type=AttachmentType.TEXT)

        if step.table:
            self.logger.attach_data(uuid4(),
                                    step_table(step),
                                    name='.table',
                                    attachment_type=AttachmentType.CSV)

    def stop_behave_step(self, result):
        status = step_status(result)
        status_details = step_status_details(result)
        self.logger.stop_step(self.current_step_uuid,
                              stop=now(),
                              status=status,
                              statusDetails=status_details)

    def flush_steps(self):
        while self.steps:
            step = self.steps.popleft()
            self.start_behave_step(step)
            self.stop_behave_step(step)

    @allure_commons.hookimpl
    def start_step(self, uuid, title, params):
        parameters = [
            Parameter(name=name, value=value)
            for name, value in params.items()
        ]
        step = TestStepResult(name=title, start=now(), parameters=parameters)
        self.logger.start_step(None, uuid, step)

    @allure_commons.hookimpl
    def stop_step(self, uuid, exc_type, exc_val, exc_tb):
        self.logger.stop_step(uuid,
                              stop=now(),
                              status=get_status(exc_val),
                              statusDetails=get_status_details(
                                  exc_type, exc_val, exc_tb))

    @allure_commons.hookimpl
    def attach_data(self, body, name, attachment_type, extension):
        self.logger.attach_data(uuid4(),
                                body,
                                name=name,
                                attachment_type=attachment_type,
                                extension=extension)

    @allure_commons.hookimpl
    def attach_file(self, source, name, attachment_type, extension):
        self.logger.attach_file(uuid4(),
                                source,
                                name=name,
                                attachment_type=attachment_type,
                                extension=extension)
class allure_robotframework(object):
    ROBOT_LISTENER_API_VERSION = 2
    DEFAULT_OUTPUT_PATH = os.path.join('output', 'allure')
    LOG_MESSAGE_FORMAT = '{full_message}<p><b>[{level}]</b> {message}</p>'
    FAIL_MESSAGE_FORMAT = '{full_message}<p style="color: red"><b>[{level}]</b> {message}</p>'

    def __init__(self, logger_path=DEFAULT_OUTPUT_PATH):
        self.stack = []
        self.items_log = {}
        self.pool_id = None
        self.links = OrderedDict()
        self._previous_keyword_failed = False
        self._traceback_message = None

        self.reporter = AllureReporter()
        self.listener = AllureListener(self.reporter)
        self.logger = AllureFileLogger(logger_path)

        allure_commons.plugin_manager.register(self.logger)
        allure_commons.plugin_manager.register(self.listener)

    def start_suite(self, name, attributes):
        if not self.pool_id:
            self.pool_id = BuiltIn().get_variable_value('${PABOTEXECUTIONPOOLID}')
            self.pool_id = int(self.pool_id) if self.pool_id else 0
        self.start_new_group(name, attributes)

    def end_suite(self, name, attributes):
        self.stop_current_group()

    def start_test(self, name, attributes):
        self.start_new_group(name, attributes)
        self.start_new_test(name, attributes)

    def end_test(self, name, attributes):
        self.stop_current_test(name, attributes)
        self.stop_current_group()

    def start_keyword(self, name, attributes):
        self.start_new_keyword(name, attributes)

    def end_keyword(self, name, attributes):
        self.end_current_keyword(name, attributes)

    def log_message(self, message):
        level = message.get('level')
        if self._previous_keyword_failed:
            self._traceback_message = message.get('message')
            self._previous_keyword_failed = False
        if level == RobotLogLevel.FAIL:
            self._previous_keyword_failed = True
            self.reporter.get_item(self.stack[-1]).statusDetails = StatusDetails(message=message.get('message'))
        self.append_message_to_last_item_log(message, level)

    def start_new_group(self, name, attributes):
        uuid = uuid4()
        self.set_suite_link(attributes.get('metadata'), uuid)
        if self.stack:
            parent_suite = self.reporter.get_last_item(TestResultContainer)
            parent_suite.children.append(uuid)
        self.stack.append(uuid)
        suite = TestResultContainer(uuid=uuid,
                                    name=name,
                                    description=attributes.get('doc'),
                                    start=now())
        self.reporter.start_group(uuid, suite)

    def stop_current_group(self):
        uuid = self.stack.pop()
        self.remove_suite_link(uuid)
        self.reporter.stop_group(uuid, stop=now())

    def start_new_test(self, name, attributes):
        uuid = uuid4()
        self.reporter.get_last_item(TestResultContainer).children.append(uuid)
        self.stack.append(uuid)
        test_case = TestResult(uuid=uuid,
                               historyId=md5(attributes.get('longname')),
                               name=name,
                               fullName=attributes.get('longname'),
                               start=now())
        self.reporter.schedule_test(uuid, test_case)

    def stop_current_test(self, name, attributes):
        uuid = self.stack.pop()
        test = self.reporter.get_test(uuid)
        test.status = utils.get_allure_status(attributes.get('status'))
        test.labels.extend(utils.get_allure_suites(attributes.get('longname')))

        test.labels.extend(allure_tags(attributes))
        for label_type in (LabelType.EPIC, LabelType.FEATURE, LabelType.STORY):
            test.labels.extend(allure_labels(attributes, label_type))
        for link_type in (LinkType.ISSUE, LinkType.TEST_CASE, LinkType.LINK):
            test.links.extend(allure_links(attributes, link_type))
        test.labels.append(Label(name=LabelType.THREAD, value=self.pool_id))
        test.labels.append(Label(name=LabelType.HOST, value=host_tag()))
        test.labels.append(Label(name=LabelType.FRAMEWORK, value='robotframework'))
        test.labels.append(Label(name=LabelType.LANGUAGE, value=platform_label()))
        test.statusDetails = StatusDetails(message=attributes.get('message'), trace=self.get_traceback_message())
        test.description = attributes.get('doc')
        last_link = list(self.links.values())[-1] if self.links else None
        if attributes.get(Severity.CRITICAL, 'no') == 'yes':
            test.labels.append(Label(name=LabelType.SEVERITY, value=Severity.CRITICAL))
        if last_link:
            test.links.append(Link(LinkType.LINK, last_link, 'Link'))
        test.stop = now()
        self.reporter.close_test(uuid)

    def start_new_keyword(self, name, attributes):
        uuid = uuid4()
        parent_uuid = self.stack[-1]
        step_name = '{} = {}'.format(attributes.get('assign')[0], name) if attributes.get('assign') else name
        args = {
            'name': step_name,
            'description': attributes.get('doc'),
            'parameters': utils.get_allure_parameters(attributes.get('args')),
            'start': now()
        }
        keyword_type = attributes.get('type')
        last_item = self.reporter.get_last_item()
        if keyword_type in RobotKeywordType.FIXTURES and not isinstance(last_item, TestStepResult):
            if isinstance(last_item, TestResult):
                parent_uuid = self.stack[-2]
            if keyword_type == RobotKeywordType.SETUP:
                self.reporter.start_before_fixture(parent_uuid, uuid, TestBeforeResult(**args))
            elif keyword_type == RobotKeywordType.TEARDOWN:
                self.reporter.start_after_fixture(parent_uuid, uuid, TestAfterResult(**args))
            self.stack.append(uuid)
            return
        self.stack.append(uuid)
        self.reporter.start_step(parent_uuid=parent_uuid,
                                 uuid=uuid,
                                 step=TestStepResult(**args))

    def end_current_keyword(self, name, attributes):
        uuid = self.stack.pop()
        if uuid in self.items_log:
            self.reporter.attach_data(uuid=uuid4(),
                                      body=self.items_log.pop(uuid).replace('\n', '<br>'),
                                      name='Keyword Log',
                                      attachment_type=AttachmentType.HTML)
        args = {
            'uuid': uuid,
            'status': utils.get_allure_status(attributes.get('status')),
            'stop': now()
        }
        keyword_type = attributes.get('type')
        parent_item = self.reporter.get_last_item()
        if keyword_type in RobotKeywordType.FIXTURES and not isinstance(parent_item, TestStepResult):
            if keyword_type == RobotKeywordType.SETUP:
                self.reporter.stop_before_fixture(**args)
                return
            elif keyword_type == RobotKeywordType.TEARDOWN:
                self.reporter.stop_after_fixture(**args)
                return
        self.reporter.stop_step(**args)

    def append_message_to_last_item_log(self, message, level):
        full_message = self.items_log[self.stack[-1]] if self.stack[-1] in self.items_log else ''
        message_format = self.FAIL_MESSAGE_FORMAT if level in RobotLogLevel.CRITICAL_LEVELS else self.LOG_MESSAGE_FORMAT
        self.items_log[self.stack[-1]] = message_format.format(full_message=full_message,
                                                               level=message.get('level'),
                                                               message=message.get('message'))

    def set_suite_link(self, metadata, uuid):
        if metadata:
            link = metadata.get('Link')
            if link:
                self.links[uuid] = link

    def remove_suite_link(self, uuid):
        if self.links.get(uuid):
            self.links.pop(uuid)

    def get_traceback_message(self):
        if BuiltIn().get_variable_value('${LOG LEVEL}') in (RobotLogLevel.DEBUG, RobotLogLevel.TRACE):
            return self._traceback_message
        return None

    def close(self):
        for plugin in [self.logger, self.listener]:
            name = allure_commons.plugin_manager.get_name(plugin)
            allure_commons.plugin_manager.unregister(name=name)
class AllureTestResult(object):
    def __init__(self):
        report_root_path = os.path.join(os.getcwd(), "reportsxxxx")
        report_dir_path = os.path.join(
            report_root_path,
            datetime.now().strftime('%Y-%m-%d-%H-%M-%S'))
        if not os.path.isdir(report_dir_path):
            os.makedirs(report_dir_path)
        for f in os.listdir(report_dir_path):
            f = os.path.join(report_dir_path, f)
            if os.path.isfile(f):
                os.unlink(f)
            elif os.path.isdir(f):
                shutil.rmtree(f)
        self.file_logger = AllureFileLogger(report_dir_path)
        allure_commons.plugin_manager.register(self.file_logger)
        self.allure_logger = AllureReporter()
        self.start_at = time.time()

    def _clean_up(self):
        name = allure_commons.plugin_manager.get_name(self.file_logger)
        allure_commons.plugin_manager.unregister(name=name)

    @staticmethod
    def allure_status(status):
        return {
            'failed': Status.FAILED,
            'broken': Status.BROKEN,
            'passed': Status.PASSED,
            'skipped': Status.SKIPPED
        }.get(status)

    @staticmethod
    def _get_err_message(err):
        exctype, value, tb = err
        return str(exctype.__name__)

    def _add_result(self, test, trace=None):
        uuid = uuid4()

        test = TestSummaryResult(**test)
        test_result = allure_TestResult(name=test.test_name, uuid=uuid)
        # test_result.status = self.allure_status(test.test_status)
        test_result.status = self.allure_status(test.test_status)

        test_result.fullName = test_result.name
        test_result.historyId = md5(test_result.fullName)

        test_result.statusDetails = StatusDetails(message=test.test_message,
                                                  trace=trace)
        self.allure_logger.schedule_test(uuid, test_result)

        self.allure_logger.attach_data(uuid4(),
                                       'aaa',
                                       name="request_result",
                                       attachment_type="text/plain",
                                       extension="txt")

        self.allure_logger.attach_data(uuid4(),
                                       json.dumps(test.test_dict,
                                                  cls=ComplexEncoder,
                                                  indent=4,
                                                  sort_keys=True,
                                                  ensure_ascii=False),
                                       name="case_dict",
                                       attachment_type="application/json",
                                       extension="json")

        self.allure_logger.close_test(uuid)

    def render_html_report(self):
        self._clean_up()

    @property
    def duration(self):
        return time.time() - self.start_at
示例#20
0
class AllureListener(object):

    def __init__(self):
        self.allure_logger = AllureReporter()
        self._cache = ItemCache()
        self._host = host_tag()
        self._thread = thread_tag()

    @allure_commons.hookimpl
    def start_step(self, uuid, title, params):
        parameters = [Parameter(name=name, value=value) for name, value in params]
        step = TestStepResult(name=title, start=now(), parameters=parameters)
        self.allure_logger.start_step(None, uuid, step)

    @allure_commons.hookimpl
    def stop_step(self, uuid, exc_type, exc_val, exc_tb):
        self.allure_logger.stop_step(uuid,
                                     stop=now(),
                                     status=get_status(exc_val),
                                     statusDetails=get_status_details(exc_type, exc_val, exc_tb))

    @allure_commons.hookimpl
    def start_fixture(self, parent_uuid, uuid, name):
        after_fixture = TestAfterResult(name=name, start=now())
        self.allure_logger.start_after_fixture(parent_uuid, uuid, after_fixture)

    @allure_commons.hookimpl
    def stop_fixture(self, parent_uuid, uuid, name, exc_type, exc_val, exc_tb):
        self.allure_logger.stop_after_fixture(uuid,
                                              stop=now(),
                                              status=get_status(exc_val),
                                              statusDetails=get_status_details(exc_type, exc_val, exc_tb))

    @pytest.hookimpl(hookwrapper=True, tryfirst=True)
    def pytest_runtest_protocol(self, item, nextitem):
        uuid = self._cache.set(item.nodeid)
        for fixturedef in _test_fixtures(item):
            group_uuid = self._cache.get(fixturedef)
            if not group_uuid:
                group_uuid = self._cache.set(fixturedef)
                group = TestResultContainer(uuid=group_uuid)
                self.allure_logger.start_group(group_uuid, group)
            self.allure_logger.update_group(group_uuid, children=uuid)

        test_case = TestResult(name=allure_name(item), uuid=uuid)
        self.allure_logger.schedule_test(uuid, test_case)

        if hasattr(item, 'function'):
            test_case.description = item.function.__doc__

        yield

        for name, value in item.callspec.params.items() if hasattr(item, 'callspec') else ():
            test_result = self.allure_logger.get_test(uuid)
            if test_result:
                test_result.parameters.append(Parameter(name, represent(value)))

        test_case.labels.extend([Label(name=name, value=value) for name, value in allure_labels(item)])
        test_case.labels.extend([Label(name=LabelType.TAG, value=value) for value in pytest_markers(item)])
        test_case.labels.append(Label(name=LabelType.HOST, value=self._host))
        test_case.labels.append(Label(name=LabelType.THREAD, value=self._thread))
        test_case.labels.append(Label(name=LabelType.FRAMEWORK, value='pytest'))
        test_case.labels.append(Label(name=LabelType.LANGUAGE, value=platform_label()))

        test_case.links += [Link(link_type, url, name) for link_type, url, name in allure_links(item)]

        test_case.fullName = allure_full_name(item)
        test_case.historyId = md5(test_case.fullName)
        test_case.labels.append(Label('package', allure_package(item)))

        uuid = self._cache.pop(item.nodeid)
        self.allure_logger.close_test(uuid)

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_call(self, item):
        uuid = self._cache.get(item.nodeid)
        test_result = self.allure_logger.get_test(uuid)
        if test_result:
            test_result.start = now()

        yield

        if test_result:
            test_result.stop = now()

    @pytest.hookimpl(hookwrapper=True)
    def pytest_fixture_setup(self, fixturedef, request):
        fixture_name = fixturedef.argname

        container_uuid = self._cache.get(fixturedef)

        if not container_uuid:
            container_uuid = self._cache.set(fixturedef)
            container = TestResultContainer(uuid=container_uuid)
            self.allure_logger.start_group(container_uuid, container)

        self.allure_logger.update_group(container_uuid, start=now())

        before_fixture_uuid = uuid4()
        before_fixture = TestBeforeResult(name=fixture_name, start=now())
        self.allure_logger.start_before_fixture(container_uuid, before_fixture_uuid, before_fixture)

        outcome = yield

        self.allure_logger.stop_before_fixture(before_fixture_uuid,
                                               stop=now(),
                                               status=get_outcome_status(outcome),
                                               statusDetails=get_outcome_status_details(outcome))

        for index, finalizer in enumerate(fixturedef._finalizer or ()):
            name = '{fixture}::{finalizer}'.format(fixture=fixturedef.argname, finalizer=finalizer.__name__)
            fixturedef._finalizer[index] = allure_commons.fixture(finalizer, parent_uuid=container_uuid, name=name)

    @pytest.hookimpl(hookwrapper=True)
    def pytest_fixture_post_finalizer(self, fixturedef):
        yield
        if hasattr(fixturedef, 'cached_result') and self._cache.get(fixturedef):
            container_uuid = self._cache.pop(fixturedef)
            self.allure_logger.stop_group(container_uuid, stop=now())

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_makereport(self, item, call):
        uuid = self._cache.set(item.nodeid)
        report = (yield).get_result()
        allure_item = self.allure_logger.get_item(uuid)
        status = allure_item.status or None
        status_details = None

        if call.excinfo and hasattr(report, 'wasxfail'):
            status_details = StatusDetails(message=report.wasxfail, trace=report.longreprtext)
        elif report.failed:
            status_details = StatusDetails(message=call.excinfo.exconly(), trace=report.longreprtext)

        if report.when == 'setup':
            if report.passed:
                status = Status.PASSED
            if report.failed:
                status = Status.BROKEN
            if report.skipped:
                status = Status.SKIPPED

        if report.when == 'call':
            if report.passed and status == Status.PASSED:
                pass
            if report.failed:
                status = Status.FAILED
            if report.skipped:
                status = Status.SKIPPED

        if report.when == 'teardown':
            if report.failed and status == Status.PASSED:
                status = Status.BROKEN

        test_result = self.allure_logger.get_test(uuid)
        if test_result:
            if status_details:
                test_result.status = status
                test_result.statusDetails = status_details
            else:
                test_result.status = status

    @allure_commons.hookimpl
    def attach_data(self, body, name, attachment_type, extension):
        self.allure_logger.attach_data(uuid4(), body, name=name, attachment_type=attachment_type, extension=extension)

    @allure_commons.hookimpl
    def attach_file(self, source, name, attachment_type, extension):
        self.allure_logger.attach_file(uuid4(), source, name=name, attachment_type=attachment_type, extension=extension)

    @allure_commons.hookimpl
    def add_link(self, url, link_type, name):
        test_result = self.allure_logger.get_test(None)
        if test_result:
            test_result.links.append(Link(link_type, url, name))

    @allure_commons.hookimpl
    def add_label(self, label_type, labels):
        test_result = self.allure_logger.get_test(None)
        for label in labels if test_result else ():
            test_result.labels.append(Label(label_type, label))
示例#21
0
 def __init__(self, config):
     self.config = config
     self.allure_logger = AllureReporter()
     self._cache = ItemCache()
     self._host = host_tag()
     self._thread = thread_tag()
示例#22
0
class AllureListener(object):

    def __init__(self, config):
        self.config = config
        self.allure_logger = AllureReporter()
        self._cache = ItemCache()
        self._host = host_tag()
        self._thread = thread_tag()

    @allure_commons.hookimpl
    def start_step(self, uuid, title, params):
        parameters = [Parameter(name=name, value=value) for name, value in params.items()]
        step = TestStepResult(name=title, start=now(), parameters=parameters)
        self.allure_logger.start_step(None, uuid, step)

    @allure_commons.hookimpl
    def stop_step(self, uuid, exc_type, exc_val, exc_tb):
        self.allure_logger.stop_step(uuid,
                                     stop=now(),
                                     status=get_status(exc_val),
                                     statusDetails=get_status_details(exc_type, exc_val, exc_tb))

    @allure_commons.hookimpl
    def start_fixture(self, parent_uuid, uuid, name):
        after_fixture = TestAfterResult(name=name, start=now())
        self.allure_logger.start_after_fixture(parent_uuid, uuid, after_fixture)

    @allure_commons.hookimpl
    def stop_fixture(self, parent_uuid, uuid, name, exc_type, exc_val, exc_tb):
        self.allure_logger.stop_after_fixture(uuid,
                                              stop=now(),
                                              status=get_status(exc_val),
                                              statusDetails=get_status_details(exc_type, exc_val, exc_tb))

    @pytest.hookimpl(hookwrapper=True, tryfirst=True)
    def pytest_runtest_protocol(self, item, nextitem):
        uuid = self._cache.push(item.nodeid)
        test_result = TestResult(name=item.name, uuid=uuid, start=now(), stop=now())
        self.allure_logger.schedule_test(uuid, test_result)
        yield

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_setup(self, item):
        if not self._cache.get(item.nodeid):
            uuid = self._cache.push(item.nodeid)
            test_result = TestResult(name=item.name, uuid=uuid, start=now(), stop=now())
            self.allure_logger.schedule_test(uuid, test_result)

        yield

        uuid = self._cache.get(item.nodeid)
        test_result = self.allure_logger.get_test(uuid)
        for fixturedef in _test_fixtures(item):
            group_uuid = self._cache.get(fixturedef)
            if not group_uuid:
                group_uuid = self._cache.push(fixturedef)
                group = TestResultContainer(uuid=group_uuid)
                self.allure_logger.start_group(group_uuid, group)
            self.allure_logger.update_group(group_uuid, children=uuid)
        params = item.callspec.params if hasattr(item, 'callspec') else {}

        test_result.name = allure_name(item, params)
        test_result.description = allure_description(item)
        test_result.descriptionHtml = allure_description_html(item)
        test_result.fullName = allure_full_name(item)
        test_result.historyId = md5(test_result.fullName)
        test_result.parameters.extend(
            [Parameter(name=name, value=represent(value)) for name, value in params.items()])

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_call(self, item):
        uuid = self._cache.get(item.nodeid)
        test_result = self.allure_logger.get_test(uuid)
        if test_result:
            test_result.start = now()
        yield
        if test_result:
            test_result.stop = now()

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_teardown(self, item):
        yield
        uuid = self._cache.get(item.nodeid)
        test_result = self.allure_logger.get_test(uuid)
        test_result.labels.extend([Label(name=name, value=value) for name, value in allure_labels(item)])
        test_result.labels.extend([Label(name=LabelType.TAG, value=value) for value in pytest_markers(item)])
        test_result.labels.extend([Label(name=name, value=value) for name, value in allure_suite_labels(item)])
        test_result.labels.append(Label(name=LabelType.HOST, value=self._host))
        test_result.labels.append(Label(name=LabelType.THREAD, value=self._thread))
        test_result.labels.append(Label(name=LabelType.FRAMEWORK, value='pytest'))
        test_result.labels.append(Label(name=LabelType.LANGUAGE, value=platform_label()))
        test_result.labels.append(Label(name='package', value=allure_package(item)))
        test_result.links.extend([Link(link_type, url, name) for link_type, url, name in allure_links(item)])

    @pytest.hookimpl(hookwrapper=True)
    def pytest_fixture_setup(self, fixturedef, request):
        fixture_name = fixturedef.argname

        container_uuid = self._cache.get(fixturedef)

        if not container_uuid:
            container_uuid = self._cache.push(fixturedef)
            container = TestResultContainer(uuid=container_uuid)
            self.allure_logger.start_group(container_uuid, container)

        self.allure_logger.update_group(container_uuid, start=now())

        before_fixture_uuid = uuid4()
        before_fixture = TestBeforeResult(name=fixture_name, start=now())
        self.allure_logger.start_before_fixture(container_uuid, before_fixture_uuid, before_fixture)

        outcome = yield

        self.allure_logger.stop_before_fixture(before_fixture_uuid,
                                               stop=now(),
                                               status=get_outcome_status(outcome),
                                               statusDetails=get_outcome_status_details(outcome))

        finalizers = getattr(fixturedef, '_finalizers', [])
        for index, finalizer in enumerate(finalizers):
            name = '{fixture}::{finalizer}'.format(fixture=fixturedef.argname,
                                                   finalizer=getattr(finalizer, "__name__", index))
            finalizers[index] = allure_commons.fixture(finalizer, parent_uuid=container_uuid, name=name)

    @pytest.hookimpl(hookwrapper=True)
    def pytest_fixture_post_finalizer(self, fixturedef):
        yield
        if hasattr(fixturedef, 'cached_result') and self._cache.get(fixturedef):
            container_uuid = self._cache.pop(fixturedef)
            self.allure_logger.stop_group(container_uuid, stop=now())

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_makereport(self, item, call):
        uuid = self._cache.get(item.nodeid)

        report = (yield).get_result()

        test_result = self.allure_logger.get_test(uuid)
        status = get_pytest_report_status(report)
        status_details = None

        if call.excinfo:
            status_details = StatusDetails(
                message=escape_non_unicode_symbols(call.excinfo.exconly()),
                trace=escape_non_unicode_symbols(report.longreprtext))
            if (status != Status.SKIPPED
                and not (call.excinfo.errisinstance(AssertionError)
                         or call.excinfo.errisinstance(pytest.fail.Exception))):
                status = Status.BROKEN

        if status == Status.PASSED and hasattr(report, 'wasxfail'):
            reason = report.wasxfail
            message = 'XPASS {reason}'.format(reason=reason) if reason else 'XPASS'
            status_details = StatusDetails(message=message)

        if report.when == 'setup':
            test_result.status = status
            test_result.statusDetails = status_details

        if report.when == 'call':
            if test_result.status == Status.PASSED:
                test_result.status = status
                test_result.statusDetails = status_details

        if report.when == 'teardown':
            if status in (Status.FAILED, Status.BROKEN) and test_result.status == Status.PASSED:
                test_result.status = status
                test_result.statusDetails = status_details

            if self.config.option.attach_capture:
                if report.caplog:
                    self.attach_data(report.caplog, "log", AttachmentType.TEXT, None)
                if report.capstdout:
                    self.attach_data(report.capstdout, "stdout", AttachmentType.TEXT, None)
                if report.capstderr:
                    self.attach_data(report.capstderr, "stderr", AttachmentType.TEXT, None)

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_logfinish(self, nodeid, location):
        yield
        uuid = self._cache.pop(nodeid)
        if uuid:
            self.allure_logger.close_test(uuid)

    @allure_commons.hookimpl
    def attach_data(self, body, name, attachment_type, extension):
        self.allure_logger.attach_data(uuid4(), body, name=name, attachment_type=attachment_type, extension=extension)

    @allure_commons.hookimpl
    def attach_file(self, source, name, attachment_type, extension):
        self.allure_logger.attach_file(uuid4(), source, name=name, attachment_type=attachment_type, extension=extension)

    @allure_commons.hookimpl
    def add_title(self, test_title):
        test_result = self.allure_logger.get_test(None)
        if test_result:
            test_result.name = test_title

    @allure_commons.hookimpl
    def add_description(self, test_description):
        test_result = self.allure_logger.get_test(None)
        if test_result:
            test_result.description = test_description

    @allure_commons.hookimpl
    def add_description_html(self, test_description_html):
        test_result = self.allure_logger.get_test(None)
        if test_result:
            test_result.descriptionHtml = test_description_html

    @allure_commons.hookimpl
    def add_link(self, url, link_type, name):
        test_result = self.allure_logger.get_test(None)
        if test_result:
            pattern = dict(self.config.option.allure_link_pattern).get(link_type, u'{}')
            url = pattern.format(url)
            test_result.links.append(Link(link_type, url, name))

    @allure_commons.hookimpl
    def add_label(self, label_type, labels):
        test_result = self.allure_logger.get_test(None)
        for label in labels if test_result else ():
            test_result.labels.append(Label(label_type, label))
示例#23
0
class AllureListener(object):
    def __init__(self, config):
        self.config = config
        self.allure_logger = AllureReporter()
        self._cache = ItemCache()

    @allure_commons.hookimpl
    def start_step(self, uuid, title, params):
        parameters = [
            Parameter(name=name, value=value) for name, value in params
        ]
        step = TestStepResult(name=title, start=now(), parameters=parameters)
        self.allure_logger.start_step(None, uuid, step)

    @allure_commons.hookimpl
    def stop_step(self, uuid, exc_type, exc_val, exc_tb):
        status = Status.PASSED
        if exc_type is not None:
            if exc_type == pytest.skip.Exception:
                status = Status.SKIPPED
            else:
                status = Status.FAILED

        self.allure_logger.stop_step(uuid, stop=now(), status=status)

    @allure_commons.hookimpl
    def start_fixture(self, parent_uuid, uuid, name):
        after_fixture = TestAfterResult(name=name, start=now())
        self.allure_logger.start_after_fixture(parent_uuid, uuid,
                                               after_fixture)

    @allure_commons.hookimpl
    def stop_fixture(self, uuid, exc_type, exc_val, exc_tb):
        self.allure_logger.stop_after_fixture(uuid, stop=now())

    @pytest.hookimpl(hookwrapper=True, tryfirst=True)
    def pytest_runtest_protocol(self, item, nextitem):
        uuid = self._cache.set(item.nodeid)
        for fixturedef in _test_fixtures(item):
            group_uuid = self._cache.get(fixturedef)
            if not group_uuid:
                group_uuid = self._cache.set(fixturedef)
                group = TestResultContainer(uuid=group_uuid)
                self.allure_logger.start_group(group_uuid, group)
            self.allure_logger.update_group(group_uuid, children=uuid)

        test_case = TestResult(name=item.name, uuid=uuid)
        self.allure_logger.schedule_test(uuid, test_case)

        yield

        test_case.labels += [
            Label(name, value) for name, value in allure_labels(item)
        ]
        test_case.links += [
            Link(link_type, url, name)
            for link_type, url, name in allure_links(item)
        ]
        test_case.labels += [
            Label(LabelType.TAG, value) for value in pytest_markers(item)
        ]

        test_case.fullName = allure_full_name(item.nodeid)
        test_case.historyId = md5(test_case.fullName)
        test_case.labels.append(Label('package', allure_package(item.nodeid)))

        uuid = self._cache.pop(item.nodeid)
        self.allure_logger.close_test(uuid)

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_call(self, item):
        uuid = self._cache.get(item.nodeid)
        self.allure_logger.update_test(uuid, start=now())
        yield
        self.allure_logger.update_test(uuid, stop=now())

    @pytest.hookimpl(hookwrapper=True)
    def pytest_fixture_setup(self, fixturedef, request):
        fixture_name = fixturedef.argname

        container_uuid = self._cache.get(fixturedef)

        if not container_uuid:
            container_uuid = self._cache.set(fixturedef)
            container = TestResultContainer(uuid=container_uuid)
            self.allure_logger.start_group(container_uuid, container)

        self.allure_logger.update_group(container_uuid, start=now())

        before_fixture_uuid = uuid4()
        before_fixture = TestBeforeResult(name=fixture_name, start=now())
        self.allure_logger.start_before_fixture(container_uuid,
                                                before_fixture_uuid,
                                                before_fixture)

        parameters = allure_parameters(fixturedef, request)
        if parameters:
            test_uuid = self._cache.get(request._pyfuncitem.nodeid)
            parameters = Parameter(**parameters) if parameters else []
            self.allure_logger.update_test(test_uuid, parameters=parameters)

        yield

        self.allure_logger.stop_before_fixture(before_fixture_uuid, stop=now())

        for index, finalizer in enumerate(fixturedef._finalizer or ()):
            name = u'{fixture}::{finalizer}'.format(
                fixture=fixturedef.argname, finalizer=finalizer.__name__)
            fixturedef._finalizer[index] = allure_commons.fixture(
                finalizer, parent_uuid=container_uuid, name=name)

    @pytest.hookimpl(hookwrapper=True)
    def pytest_fixture_post_finalizer(self, fixturedef):
        yield
        if hasattr(fixturedef,
                   'cached_result') and self._cache.get(fixturedef):
            container_uuid = self._cache.pop(fixturedef)
            self.allure_logger.stop_group(container_uuid, stop=now())

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_makereport(self, item, call):
        uuid = self._cache.set(item.nodeid)
        report = (yield).get_result()
        allure_item = self.allure_logger.get_item(uuid)
        status = allure_item.status or None
        status_details = None

        if call.excinfo and hasattr(call.excinfo.value, 'msg'):
            status_details = StatusDetails(message=call.excinfo.value.msg)
        elif hasattr(report, 'wasxfail'):
            status_details = StatusDetails(message=report.wasxfail)
        elif report.failed:
            status_details = StatusDetails(message=call.excinfo.exconly(),
                                           trace=report.longreprtext)

        if report.when == 'setup':
            if report.passed:
                status = Status.PASSED
            if report.failed:
                status = Status.BROKEN
            if report.skipped:
                status = Status.SKIPPED

        if report.when == 'call':
            if report.passed and status == Status.PASSED:
                pass
            if report.failed:
                status = Status.FAILED
            if report.skipped:
                status = Status.SKIPPED

        if report.when == 'teardown':
            if report.failed and status == Status.PASSED:
                status = Status.BROKEN

        if status_details:
            self.allure_logger.update_test(uuid,
                                           status=status,
                                           statusDetails=status_details)
        else:
            self.allure_logger.update_test(uuid, status=status)

    @allure_commons.hookimpl
    def attach_data(self, body, name, attachment_type, extension):
        self.allure_logger.attach_data(uuid4(),
                                       body,
                                       name=name,
                                       attachment_type=attachment_type,
                                       extension=extension)

    @allure_commons.hookimpl
    def attach_file(self, source, name, attachment_type, extension):
        self.allure_logger.attach_file(uuid4(),
                                       source,
                                       name=name,
                                       attachment_type=attachment_type,
                                       extension=extension)

    @allure_commons.hookimpl
    def add_link(self, url, link_type, name):
        self.allure_logger.update_test(None,
                                       links=[Link(link_type, url, name)])

    @allure_commons.hookimpl
    def add_label(self, label_type, labels):
        for label in labels:
            self.allure_logger.update_test(None,
                                           labels=Label(label_type, label))
class AllureListener(object):
    def __init__(self, config):
        self.config = config
        self.allure_logger = AllureReporter()
        self._cache = ItemCache()
        self._host = host_tag()
        self._thread = thread_tag()

    @allure_commons.hookimpl
    def start_step(self, uuid, title, params):
        parameters = [
            Parameter(name=name, value=value)
            for name, value in params.items()
        ]
        step = TestStepResult(name=title, start=now(), parameters=parameters)
        self.allure_logger.start_step(None, uuid, step)

    @allure_commons.hookimpl
    def stop_step(self, uuid, exc_type, exc_val, exc_tb):
        self.allure_logger.stop_step(uuid,
                                     stop=now(),
                                     status=get_status(exc_val),
                                     statusDetails=get_status_details(
                                         exc_type, exc_val, exc_tb))

    @allure_commons.hookimpl
    def start_fixture(self, parent_uuid, uuid, name):
        after_fixture = TestAfterResult(name=name, start=now())
        self.allure_logger.start_after_fixture(parent_uuid, uuid,
                                               after_fixture)

    @allure_commons.hookimpl
    def stop_fixture(self, parent_uuid, uuid, name, exc_type, exc_val, exc_tb):
        self.allure_logger.stop_after_fixture(uuid,
                                              stop=now(),
                                              status=get_status(exc_val),
                                              statusDetails=get_status_details(
                                                  exc_type, exc_val, exc_tb))

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_setup(self, item):
        uuid = self._cache.set(item.nodeid)
        test_result = TestResult(name=item.name, uuid=uuid)
        self.allure_logger.schedule_test(uuid, test_result)

        yield
        uuid = self._cache.get(item.nodeid)
        test_result = self.allure_logger.get_test(uuid)
        for fixturedef in _test_fixtures(item):
            group_uuid = self._cache.get(fixturedef)
            if not group_uuid:
                group_uuid = self._cache.set(fixturedef)
                group = TestResultContainer(uuid=group_uuid)
                self.allure_logger.start_group(group_uuid, group)
            self.allure_logger.update_group(group_uuid, children=uuid)
        params = item.callspec.params if hasattr(item, 'callspec') else {}

        test_result.name = allure_name(item, params)
        test_result.description = allure_description(item)
        test_result.descriptionHtml = allure_description_html(item)
        test_result.fullName = allure_full_name(item)
        test_result.historyId = md5(test_result.fullName)
        test_result.parameters.extend([
            Parameter(name=name, value=represent(value))
            for name, value in params.items()
        ])

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_call(self, item):
        uuid = self._cache.get(item.nodeid)
        test_result = self.allure_logger.get_test(uuid)
        if test_result:
            test_result.start = now()
        yield
        if test_result:
            test_result.stop = now()

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_teardown(self, item):
        yield
        uuid = self._cache.get(item.nodeid)
        test_result = self.allure_logger.get_test(uuid)
        test_result.labels.extend([
            Label(name=name, value=value)
            for name, value in allure_labels(item)
        ])
        test_result.labels.extend([
            Label(name=LabelType.TAG, value=value)
            for value in pytest_markers(item)
        ])
        test_result.labels.extend([
            Label(name=LabelType.TAG, value=value)
            for value in pytest_markers(item)
        ])
        test_result.labels.extend([
            Label(name=name, value=value)
            for name, value in allure_suite_labels(item)
        ])
        test_result.labels.append(Label(name=LabelType.HOST, value=self._host))
        test_result.labels.append(
            Label(name=LabelType.THREAD, value=self._thread))
        test_result.labels.append(
            Label(name=LabelType.FRAMEWORK, value='pytest'))
        test_result.labels.append(
            Label(name=LabelType.LANGUAGE, value=platform_label()))
        test_result.labels.append(
            Label(name='package', value=allure_package(item)))
        test_result.links.extend([
            Link(link_type, url, name)
            for link_type, url, name in allure_links(item)
        ])

    @pytest.hookimpl(hookwrapper=True)
    def pytest_fixture_setup(self, fixturedef, request):
        fixture_name = fixturedef.argname

        container_uuid = self._cache.get(fixturedef)

        if not container_uuid:
            container_uuid = self._cache.set(fixturedef)
            container = TestResultContainer(uuid=container_uuid)
            self.allure_logger.start_group(container_uuid, container)

        self.allure_logger.update_group(container_uuid, start=now())

        before_fixture_uuid = uuid4()
        before_fixture = TestBeforeResult(name=fixture_name, start=now())
        self.allure_logger.start_before_fixture(container_uuid,
                                                before_fixture_uuid,
                                                before_fixture)

        outcome = yield

        self.allure_logger.stop_before_fixture(
            before_fixture_uuid,
            stop=now(),
            status=get_outcome_status(outcome),
            statusDetails=get_outcome_status_details(outcome))

        finalizers = getattr(fixturedef, '_finalizers', [])
        for index, finalizer in enumerate(finalizers):
            name = '{fixture}::{finalizer}'.format(fixture=fixturedef.argname,
                                                   finalizer=getattr(
                                                       finalizer, "__name__",
                                                       index))
            finalizers[index] = allure_commons.fixture(
                finalizer, parent_uuid=container_uuid, name=name)

    @pytest.hookimpl(hookwrapper=True)
    def pytest_fixture_post_finalizer(self, fixturedef):
        yield
        if hasattr(fixturedef,
                   'cached_result') and self._cache.get(fixturedef):
            container_uuid = self._cache.pop(fixturedef)
            self.allure_logger.stop_group(container_uuid, stop=now())

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_makereport(self, item, call):
        uuid = self._cache.set(item.nodeid)

        report = (yield).get_result()

        test_result = self.allure_logger.get_test(uuid)
        status = get_pytest_report_status(report)
        status_details = None

        if call.excinfo:
            status_details = StatusDetails(
                message=escape_non_unicode_symbols(call.excinfo.exconly()),
                trace=escape_non_unicode_symbols(report.longreprtext))
            if (status != Status.SKIPPED and
                    not (call.excinfo.errisinstance(AssertionError) or
                         call.excinfo.errisinstance(pytest.fail.Exception))):
                status = Status.BROKEN

        if status == Status.PASSED and hasattr(report, 'wasxfail'):
            reason = report.wasxfail
            message = 'XPASS {reason}'.format(
                reason=reason) if reason else 'XPASS'
            status_details = StatusDetails(message=message)

        if report.when == 'setup':
            test_result.status = status
            test_result.statusDetails = status_details

        if report.when == 'call':
            if test_result.status == Status.PASSED:
                test_result.status = status
                test_result.statusDetails = status_details

        if report.when == 'teardown':
            if status in (Status.FAILED, Status.BROKEN
                          ) and test_result.status == Status.PASSED:
                test_result.status = status
                test_result.statusDetails = status_details

            if self.config.option.attach_capture:
                # Capture at teardown contains data from whole test (setup, call, teardown)
                self.attach_data(report.caplog, "log", AttachmentType.TEXT,
                                 None)
                self.attach_data(report.capstdout, "stdout",
                                 AttachmentType.TEXT, None)
                self.attach_data(report.capstderr, "stderr",
                                 AttachmentType.TEXT, None)

            uuid = self._cache.pop(item.nodeid)
            self.allure_logger.close_test(uuid)

    @allure_commons.hookimpl
    def attach_data(self, body, name, attachment_type, extension):
        self.allure_logger.attach_data(uuid4(),
                                       body,
                                       name=name,
                                       attachment_type=attachment_type,
                                       extension=extension)

    @allure_commons.hookimpl
    def attach_file(self, source, name, attachment_type, extension):
        self.allure_logger.attach_file(uuid4(),
                                       source,
                                       name=name,
                                       attachment_type=attachment_type,
                                       extension=extension)

    @allure_commons.hookimpl
    def add_title(self, test_title):
        test_result = self.allure_logger.get_test(None)
        if test_result:
            test_result.name = test_title

    @allure_commons.hookimpl
    def add_description(self, test_description):
        test_result = self.allure_logger.get_test(None)
        if test_result:
            test_result.description = test_description

    @allure_commons.hookimpl
    def add_description_html(self, test_description_html):
        test_result = self.allure_logger.get_test(None)
        if test_result:
            test_result.descriptionHtml = test_description_html

    @allure_commons.hookimpl
    def add_link(self, url, link_type, name):
        test_result = self.allure_logger.get_test(None)
        if test_result:
            pattern = dict(self.config.option.allure_link_pattern).get(
                link_type, u'{}')
            url = pattern.format(url)
            test_result.links.append(Link(link_type, url, name))

    @allure_commons.hookimpl
    def add_label(self, label_type, labels):
        test_result = self.allure_logger.get_test(None)
        for label in labels if test_result else ():
            test_result.labels.append(Label(label_type, label))
示例#25
0
class AllureListener(object):
    def __init__(self):
        self.logger = AllureReporter()
        self.current_step_uuid = None
        self.execution_context = Context()
        self.fixture_context = Context()
        self.steps = deque()

    def __del__(self):
        for group in self.fixture_context.exit():
            group.children.extend(self.execution_context)
            self.logger.stop_group(group.uuid)

    @allure_commons.hookimpl
    def start_fixture(self, parent_uuid, uuid, name, parameters):
        parameters = [Parameter(name=param_name, value=param_value) for param_name, param_value in parameters]

        if name in FIXTURES and not self.fixture_context:
            group = TestResultContainer(uuid=uuid4())
            self.logger.start_group(group.uuid, group)
            self.fixture_context.append(group)

        if name in BEFORE_FIXTURES:
            fixture = TestBeforeResult(name=name, start=now(), parameters=parameters)
            for group in self.fixture_context:
                self.logger.start_before_fixture(group.uuid, uuid, fixture)

        elif name in AFTER_FIXTURES:
            fixture = TestAfterResult(name=name, start=now(), parameters=parameters)
            for group in self.fixture_context:
                self.logger.start_after_fixture(group.uuid, uuid, fixture)

    @allure_commons.hookimpl
    def stop_fixture(self, parent_uuid, uuid, name, exc_type, exc_val, exc_tb):
        if name in FIXTURES:
            status = fixture_status(exc_val, exc_tb)
            status_details = fixture_status_details(exc_val, exc_tb)
            self.logger.stop_before_fixture(uuid=uuid, stop=now(), status=status, statusDetails=status_details)

    def start_feature(self):
        self.execution_context.enter()
        self.fixture_context.enter()

    def stop_feature(self):
        uuids = self.execution_context.exit()
        for group in self.fixture_context.exit():
            group.children.extend(uuids)
            self.logger.stop_group(group.uuid)
        self.execution_context.extend(uuids)

    @allure_commons.hookimpl
    def start_test(self, parent_uuid, uuid, name, parameters, context):
        scenario = context['scenario']
        self.fixture_context.enter()
        self.execution_context.enter()
        self.execution_context.append(uuid)

        test_case = TestResult(uuid=uuid, start=now())

        test_case.name = scenario_name(scenario)
        test_case.historyId = scenario_history_id(scenario)
        test_case.description = '\n'.join(scenario.description)

        labels = []
        feature_label = Label(name=LabelType.FEATURE.value, value=scenario.feature.name)
        severity = (Label(name=LabelType.SEVERITY.value, value=scenario_severity(scenario).value))
        labels.append(feature_label)
        labels.append(severity)
        labels += [Label(name=LabelType.TAG.value, value=tag) for tag in scenario_tags(scenario)]

        test_case.parameters = scenario_parameters(scenario)
        test_case.labels = labels

        self.logger.schedule_test(uuid, test_case)

    @allure_commons.hookimpl
    def stop_test(self, parent_uuid, uuid, name, context, exc_type, exc_val, exc_tb):
        scenario = context['scenario']
        self.flush_steps()
        status = scenario_status(scenario)
        status_details = scenario_status_details(scenario)
        self.logger.update_test(uuid, stop=now(), status=status, statusDetails=status_details)
        self.logger.close_test(uuid)
        self.current_step_uuid = None

        for group in self.fixture_context.exit():
            group.children.append(uuid)
            self.logger.stop_group(group.uuid)

        self.execution_context.exit()
        self.execution_context.append(uuid)

    def schedule_step(self, step):
        self.steps.append(step)

    def match_step(self, match):
        step = self.steps.popleft()
        self.start_step(step)

    def start_step(self, step):

        self.current_step_uuid = uuid4()
        name = u'{keyword} {title}'.format(keyword=step.keyword, title=step.name)

        allure_step = TestStepResult(name=name, start=now())
        self.logger.start_step(None, self.current_step_uuid, allure_step)

        if step.text:
            self.logger.attach_data(uuid4(), step.text, name='.text', attachment_type=AttachmentType.TEXT)

        if step.table:
            self.logger.attach_data(uuid4(), step_table(step), name='.table', attachment_type=AttachmentType.CSV)

    def stop_step(self, result):
        status = step_status(result)
        status_details = step_status_details(result)
        self.logger.stop_step(self.current_step_uuid, stop=now(), status=status, statusDetails=status_details)

    def flush_steps(self):
        while self.steps:
            step = self.steps.popleft()
            self.start_step(step)
            self.stop_step(step)

    @allure_commons.hookimpl
    def attach_data(self, body, name, attachment_type, extension):
        self.logger.attach_data(uuid4(), body, name=name, attachment_type=attachment_type, extension=extension)

    @allure_commons.hookimpl
    def attach_file(self, source, name, attachment_type, extension):
        self.logger.attach_file(uuid4(), source, name=name, attachment_type=attachment_type, extension=extension)
示例#26
0
 def __init__(self):
     self.allure_lifecycle = AllureReporter()
 def __init__(self, config):
     self.config = config
     self.allure_logger = AllureReporter()
     self._cache = ItemCache()
     self._host = host_tag()
     self._thread = thread_tag()
示例#28
0
class AllureListener(object):
    def __init__(self, behave_config):
        self.behave_config = behave_config
        self.logger = AllureReporter()
        self.current_step_uuid = None
        self.current_scenario_uuid = None
        self.execution_context = Context()
        self.fixture_context = Context()
        self.steps = deque()

    def __del__(self):
        for group in self.fixture_context.exit():
            group.children.extend(self.execution_context)
            self.logger.stop_group(group.uuid)

    @allure_commons.hookimpl
    def start_fixture(self, parent_uuid, uuid, name, parameters):
        parameters = [Parameter(name=param_name, value=param_value) for param_name, param_value in parameters.items()]

        if name in FIXTURES and not self.fixture_context:
            group = TestResultContainer(uuid=uuid4())
            self.logger.start_group(group.uuid, group)
            self.fixture_context.append(group)

        if name in BEFORE_FIXTURES:
            fixture = TestBeforeResult(name=name, start=now(), parameters=parameters)
            for group in self.fixture_context:
                self.logger.start_before_fixture(group.uuid, uuid, fixture)

        elif name in AFTER_FIXTURES:
            fixture = TestAfterResult(name=name, start=now(), parameters=parameters)
            for group in self.fixture_context:
                self.logger.start_after_fixture(group.uuid, uuid, fixture)

    @allure_commons.hookimpl
    def stop_fixture(self, parent_uuid, uuid, name, exc_type, exc_val, exc_tb):
        if name in FIXTURES:
            self.logger.stop_before_fixture(uuid=uuid,
                                            stop=now(),
                                            status=get_status(exc_val),
                                            statusDetails=get_status_details(exc_type, exc_val, exc_tb))

    def start_feature(self):
        self.execution_context.enter()
        self.fixture_context.enter()

    def stop_feature(self):
        uuids = self.execution_context.exit()
        for group in self.fixture_context.exit():
            group.children.extend(uuids)
            self.logger.stop_group(group.uuid)
        self.execution_context.extend(uuids)

    @allure_commons.hookimpl
    def start_test(self, parent_uuid, uuid, name, parameters, context):
        self.start_scenario(context['scenario'])

    def start_scenario(self, scenario):
        self.current_scenario_uuid = uuid4()
        self.fixture_context.enter()
        self.execution_context.enter()
        self.execution_context.append(self.current_scenario_uuid)

        test_case = TestResult(uuid=self.current_scenario_uuid, start=now())
        test_case.name = scenario_name(scenario)
        test_case.historyId = scenario_history_id(scenario)
        test_case.description = '\n'.join(scenario.description)
        test_case.parameters = scenario_parameters(scenario)
        test_case.labels.extend([Label(name=LabelType.TAG, value=tag) for tag in scenario_tags(scenario)])
        test_case.labels.append(Label(name=LabelType.SEVERITY, value=scenario_severity(scenario).value))
        test_case.labels.append(Label(name=LabelType.FEATURE, value=scenario.feature.name))
        test_case.labels.append(Label(name=LabelType.FRAMEWORK, value='behave'))
        test_case.labels.append(Label(name=LabelType.LANGUAGE, value=platform_label()))

        self.logger.schedule_test(self.current_scenario_uuid, test_case)

    @allure_commons.hookimpl
    def stop_test(self, parent_uuid, uuid, name, context, exc_type, exc_val, exc_tb):
        self.stop_scenario(context['scenario'])

    def stop_scenario(self, scenario):
        if scenario.status == 'skipped' and not self.behave_config.show_skipped:
            self.logger.drop_test(self.current_scenario_uuid)
        else:
            status = scenario_status(scenario)
            status_details = scenario_status_details(scenario)

            self.flush_steps()
            test_result = self.logger.get_test(self.current_scenario_uuid)
            test_result.stop = now()
            test_result.status = status
            test_result.statusDetails = status_details
            self.logger.close_test(self.current_scenario_uuid)
            self.current_step_uuid = None

            for group in self.fixture_context.exit():
                group.children.append(self.current_scenario_uuid)
                self.logger.stop_group(group.uuid)

        self.execution_context.exit()
        self.execution_context.append(self.current_scenario_uuid)
        self.current_scenario_uuid = None

    def schedule_step(self, step):
        self.steps.append(step)

    def match_step(self, match):
        step = self.steps.popleft()
        self.start_behave_step(step)

    def start_behave_step(self, step):

        self.current_step_uuid = uuid4()
        name = u'{keyword} {title}'.format(keyword=step.keyword, title=step.name)

        allure_step = TestStepResult(name=name, start=now())
        self.logger.start_step(None, self.current_step_uuid, allure_step)

        if step.text:
            self.logger.attach_data(uuid4(), step.text, name='.text', attachment_type=AttachmentType.TEXT)

        if step.table:
            self.logger.attach_data(uuid4(), step_table(step), name='.table', attachment_type=AttachmentType.CSV)

    def stop_behave_step(self, result):
        status = step_status(result)
        status_details = step_status_details(result)
        self.logger.stop_step(self.current_step_uuid, stop=now(), status=status, statusDetails=status_details)

    def flush_steps(self):
        while self.steps:
            step = self.steps.popleft()
            self.start_behave_step(step)
            self.stop_behave_step(step)

    @allure_commons.hookimpl
    def start_step(self, uuid, title, params):
        parameters = [Parameter(name=name, value=value) for name, value in params.items()]
        step = TestStepResult(name=title, start=now(), parameters=parameters)
        self.logger.start_step(None, uuid, step)

    @allure_commons.hookimpl
    def stop_step(self, uuid, exc_type, exc_val, exc_tb):
        self.logger.stop_step(uuid,
                              stop=now(),
                              status=get_status(exc_val),
                              statusDetails=get_status_details(exc_type, exc_val, exc_tb))

    @allure_commons.hookimpl
    def attach_data(self, body, name, attachment_type, extension):
        self.logger.attach_data(uuid4(), body, name=name, attachment_type=attachment_type, extension=extension)

    @allure_commons.hookimpl
    def attach_file(self, source, name, attachment_type, extension):
        self.logger.attach_file(uuid4(), source, name=name, attachment_type=attachment_type, extension=extension)
示例#29
0
 def __init__(self, config):
     self.config = config
     self.allure_logger = AllureReporter()
     self._cache = ItemCache()
示例#30
0
class AllureListener(object):
    def __init__(self, behave_config):
        self.behave_config = behave_config
        self.issue_pattern = behave_config.userdata.get(
            'AllureFormatter.issue_pattern', None)
        self.link_pattern = behave_config.userdata.get(
            'AllureFormatter.link_pattern', None)
        self.hide_excluded = behave_config.userdata.get(
            'AllureFormatter.hide_excluded', False)
        self.logger = AllureReporter()
        self.current_step_uuid = None
        self.current_scenario_uuid = None
        self.group_context = GroupContext(self.logger)
        self.group_context.enter()
        self.steps = deque()

    def start_file(self):
        self.group_context.enter()

    @allure_commons.hookimpl
    def start_fixture(self, parent_uuid, uuid, name, parameters):
        # parameters = [Parameter(name=param_name, value=param_value) for param_name, param_value in parameters.items()]

        if name.startswith("before_"):
            name = get_hook_name(name, parameters)
            fixture = TestBeforeResult(name=name, start=now(), parameters=None)
            group = self.group_context.current_group()
            self.logger.start_before_fixture(group.uuid, uuid, fixture)

        elif name.startswith("after_"):
            name = get_hook_name(name, parameters)
            fixture = TestAfterResult(name=name, start=now(), parameters=None)
            group = self.group_context.current_group()
            self.logger.start_after_fixture(group.uuid, uuid, fixture)

    @allure_commons.hookimpl
    def stop_fixture(self, parent_uuid, uuid, name, exc_type, exc_val, exc_tb):
        self.logger.stop_before_fixture(uuid=uuid,
                                        stop=now(),
                                        status=get_status(exc_val),
                                        statusDetails=get_status_details(
                                            exc_type, exc_val, exc_tb))

    def stop_feature(self):
        self.group_context.exit()

    @allure_commons.hookimpl
    def start_test(self, parent_uuid, uuid, name, parameters, context):
        self.start_scenario(context['scenario'])

    def start_scenario(self, scenario):
        self.current_scenario_uuid = uuid4()
        self.group_context.enter()

        test_case = TestResult(uuid=self.current_scenario_uuid, start=now())
        test_case.name = scenario_name(scenario)
        test_case.fullName = get_fullname(scenario)
        test_case.historyId = scenario_history_id(scenario)
        test_case.description = '\n'.join(scenario.description)
        test_case.parameters = scenario_parameters(scenario)

        test_case.links.extend(
            scenario_links(scenario,
                           issue_pattern=self.issue_pattern,
                           link_pattern=self.link_pattern))
        test_case.labels.extend(scenario_labels(scenario))
        test_case.labels.append(
            Label(name=LabelType.FEATURE, value=scenario.feature.name))
        test_case.labels.append(Label(name=LabelType.FRAMEWORK,
                                      value='behave'))
        test_case.labels.append(
            Label(name=LabelType.LANGUAGE, value=platform_label()))

        self.logger.schedule_test(self.current_scenario_uuid, test_case)

    @allure_commons.hookimpl
    def stop_test(self, parent_uuid, uuid, name, context, exc_type, exc_val,
                  exc_tb):
        self.stop_scenario(context['scenario'])

    def stop_scenario(self, scenario):
        should_run = (scenario.should_run_with_tags(self.behave_config.tags)
                      and scenario.should_run_with_name_select(
                          self.behave_config))
        should_drop_skipped_by_option = scenario.status == 'skipped' and not self.behave_config.show_skipped
        should_drop_excluded = self.hide_excluded and (
            scenario.skip_reason == TEST_PLAN_SKIP_REASON or not should_run)

        if should_drop_skipped_by_option or should_drop_excluded:
            self.logger.drop_test(self.current_scenario_uuid)
        else:
            status = scenario_status(scenario)
            status_details = scenario_status_details(scenario)

            self.flush_steps()
            test_result = self.logger.get_test(self.current_scenario_uuid)
            test_result.stop = now()
            test_result.status = status
            test_result.statusDetails = status_details
            self.logger.close_test(self.current_scenario_uuid)
            self.current_step_uuid = None
            self.group_context.append_test(self.current_scenario_uuid)
            self.group_context.exit()

        self.current_scenario_uuid = None

    def schedule_step(self, step):
        self.steps.append(step)

    def match_step(self, match):
        step = self.steps.popleft()
        self.start_behave_step(step)

    def start_behave_step(self, step):

        self.current_step_uuid = uuid4()
        name = u'{keyword} {title}'.format(keyword=step.keyword,
                                           title=step.name)

        allure_step = TestStepResult(name=name, start=now())
        self.logger.start_step(None, self.current_step_uuid, allure_step)

        if step.text:
            self.logger.attach_data(uuid4(),
                                    step.text,
                                    name='.text',
                                    attachment_type=AttachmentType.TEXT)

        if step.table:
            self.logger.attach_data(uuid4(),
                                    step_table(step),
                                    name='.table',
                                    attachment_type=AttachmentType.CSV)

    def stop_behave_step(self, result):
        status = step_status(result)
        status_details = step_status_details(result)
        self.logger.stop_step(self.current_step_uuid,
                              stop=now(),
                              status=status,
                              statusDetails=status_details)

    def flush_steps(self):
        while self.steps:
            step = self.steps.popleft()
            self.start_behave_step(step)
            self.stop_behave_step(step)

    @allure_commons.hookimpl
    def start_step(self, uuid, title, params):
        parameters = [
            Parameter(name=name, value=value)
            for name, value in params.items()
        ]
        step = TestStepResult(name=title, start=now(), parameters=parameters)
        self.logger.start_step(None, uuid, step)

    @allure_commons.hookimpl
    def stop_step(self, uuid, exc_type, exc_val, exc_tb):
        self.logger.stop_step(uuid,
                              stop=now(),
                              status=get_status(exc_val),
                              statusDetails=get_status_details(
                                  exc_type, exc_val, exc_tb))

    @allure_commons.hookimpl
    def attach_data(self, body, name, attachment_type, extension):
        self.logger.attach_data(uuid4(),
                                body,
                                name=name,
                                attachment_type=attachment_type,
                                extension=extension)

    @allure_commons.hookimpl
    def attach_file(self, source, name, attachment_type, extension):
        self.logger.attach_file(uuid4(),
                                source,
                                name=name,
                                attachment_type=attachment_type,
                                extension=extension)

    @allure_commons.hookimpl
    def add_description(self, test_description):
        test_result = self.logger.get_test(None)
        if test_result:
            test_result.description = test_description

    @allure_commons.hookimpl
    def add_description_html(self, test_description_html):
        test_result = self.logger.get_test(None)
        if test_result:
            test_result.descriptionHtml = test_description_html

    @allure_commons.hookimpl
    def add_link(self, url, link_type, name):
        test_result = self.logger.get_test(None)
        if test_result:
            pattern = u'{}'
            if link_type == LinkType.ISSUE and self.issue_pattern:
                pattern = self.issue_pattern
            elif link_type == LinkType.LINK and self.link_pattern:
                pattern = self.link_pattern

            link_url = pattern.format(url)
            new_link = Link(link_type, link_url,
                            link_url if name is None else name)
            for link in test_result.links:
                if link.url == new_link.url:
                    return

            test_result.links.append(new_link)

    def stop_session(self):
        self.group_context.exit()