Ejemplo n.º 1
0
class AllureCollectionListener(object):
    """
    Listens to pytest collection-related hooks
    to generate reports for modules that failed to collect.
    """
    def __init__(self, logdir):
        self.impl = AllureImpl(logdir)
        self.fails = []

    def pytest_collectreport(self, report):
        if not report.passed:
            if report.failed:
                status = Status.BROKEN
            else:
                status = Status.SKIPPED

            self.fails.append(CollectFail(name=mangle_testnames(report.nodeid.split("::"))[-1],
                                          status=status,
                                          message=get_exception_message(report),
                                          trace=report.longrepr))

    def pytest_collection_finish(self):
        """
        Creates a testsuite with collection failures if there were any.
        """

        if self.fails:
            self.impl.start_suite(name='test_collection_phase',
                                  title='Collection phase',
                                  description='This is the tests collection phase. Failures are modules that failed to collect.')
            for fail in self.fails:
                self.impl.start_case(name=fail.name)
                self.impl.stop_case(status=fail.status, message=fail.message, trace=fail.trace)
            self.impl.stop_suite()
Ejemplo n.º 2
0
class AllureCollectionListener(object):
    """
    Listens to pytest collection-related hooks
    to generate reports for modules that failed to collect.
    """
    def __init__(self, logdir):
        self.impl = AllureImpl(logdir)
        self.fails = []

    def pytest_collectreport(self, report):
        if not report.passed:
            if report.failed:
                status = Status.BROKEN
            else:
                status = Status.SKIPPED

            self.fails.append(CollectFail(name=mangle_testnames(report.nodeid.split("::"))[-1],
                                          status=status,
                                          message=get_exception_message(report),
                                          trace=report.longrepr))

    def pytest_collection_finish(self):
        """
        Creates a testsuite with collection failures if there were any.
        """

        if self.fails:
            self.impl.start_suite(name='test_collection_phase',
                                  title='Collection phase',
                                  description='This is the tests collection phase. Failures are modules that failed to collect.')
            for fail in self.fails:
                self.impl.start_case(name=fail.name)
                self.impl.stop_case(status=fail.status, message=fail.message, trace=fail.trace)
            self.impl.stop_suite()
Ejemplo n.º 3
0
class AllureTestListener(object):
    """
    Listens to pytest hooks to generate reports for common tests.
    """
    def __init__(self, logdir, config):
        self.impl = AllureImpl(logdir)
        self.config = config

        # FIXME: maybe we should write explicit wrappers?
        self.attach = self.impl.attach
        self.start_step = self.impl.start_step
        self.stop_step = self.impl.stop_step

        self.testsuite = None

    def _stop_case(self, report, status=None):
        """
        Finalizes with important data the test at the top of ``self.stack`` and returns it
        """
        [self.attach(name, contents, AttachmentType.TEXT) for (name, contents) in dict(report.sections).items()]

        if status in FAILED_STATUSES:
            self.impl.stop_case(status,
                                message=get_exception_message(report),
                                trace=report.longrepr or report.wasxfail)
        elif status == Status.SKIPPED:
            skip_message = type(report.longrepr) == tuple and \
                report.longrepr[2] or report.wasxfail
            trim_msg_len = 89
            short_message = skip_message.split('\n')[0][:trim_msg_len]

            # FIXME: see pytest.runner.pytest_runtest_makereport
            self.impl.stop_case(status,
                                message=(short_message + '...' *
                                         (len(skip_message) > trim_msg_len)),
                                trace=None if short_message ==
                                skip_message else skip_message)
        else:
            self.impl.stop_case(status)

    def pytest_runtest_protocol(self, __multicall__, item, nextitem):
        if not self.testsuite:
            module = parent_module(item)
            self.impl.start_suite(name='.'.join(mangle_testnames(module.nodeid.split("::"))),
                                  description=module.module.__doc__ or None)
            self.testsuite = 'Yes'

        name = '.'.join(mangle_testnames([x.name for x in parent_down_from_module(item)]))
        self.impl.start_case(name, description=item.function.__doc__, labels=labels_of(item))
        result = __multicall__.execute()

        if not nextitem or parent_module(item) != parent_module(nextitem):
            self.impl.stop_suite()
            self.testsuite = None

        return result

    def pytest_runtest_logreport(self, report):
        if report.passed:
            if report.when == "call":  # ignore setup/teardown
                self._stop_case(report, status=Status.PASSED)
        elif report.failed:
            if report.when != "call":
                self._stop_case(report, status=Status.BROKEN)
            else:
                self._stop_case(report, status=Status.FAILED)
        elif report.skipped:
                self._stop_case(report, status=Status.SKIPPED)

    def pytest_runtest_makereport(self, item, call, __multicall__):  # @UnusedVariable
        """
        That's the place we inject extra data into the report object from the actual Item.
        """

        report = __multicall__.execute()
        report.__dict__.update(
            exception=call.excinfo,
            result=self.config.hook.pytest_report_teststatus(report=report)[0])  # get the failed/passed/xpassed thingy
        return report

    def pytest_sessionfinish(self):
        if self.testsuite:
            self.impl.stop_suite()
            self.testsuite = None
Ejemplo n.º 4
0
class AllureTestListener(object):
    """
    Listens to pytest hooks to generate reports for common tests.
    """
    def __init__(self, logdir, config):
        self.impl = AllureImpl(logdir)
        self.config = config

        # FIXME: maybe we should write explicit wrappers?
        self.attach = self.impl.attach
        self.start_step = self.impl.start_step
        self.stop_step = self.impl.stop_step

        self.testsuite = None

    def _stop_case(self, report, status=None):
        """
        Finalizes with important data the test at the top of ``self.stack`` and returns it
        """
        [
            self.attach(name, contents, AttachmentType.TEXT)
            for (name, contents) in dict(report.sections).items()
        ]

        if status in FAILED_STATUSES:
            self.impl.stop_case(status,
                                message=get_exception_message(report),
                                trace=report.longrepr or report.wasxfail)
        elif status in SKIPPED_STATUSES:
            skip_message = type(
                report.longrepr
            ) == tuple and report.longrepr[2] or report.wasxfail
            trim_msg_len = 89
            short_message = skip_message.split('\n')[0][:trim_msg_len]

            # FIXME: see pytest.runner.pytest_runtest_makereport
            self.impl.stop_case(
                status,
                message=(short_message + '...' *
                         (len(skip_message) > trim_msg_len)),
                trace=status == Status.PENDING and report.longrepr
                or short_message != skip_message and skip_message or None)
        else:
            self.impl.stop_case(status)

    @pytest.mark.hookwrapper
    def pytest_runtest_protocol(self, item, nextitem):
        if not self.testsuite:
            module = parent_module(item)

            self.impl.start_suite(name=module.module.__name__,
                                  description=module.module.__doc__ or None)
            self.testsuite = 'Yes'

        name = '.'.join(
            mangle_testnames([x.name for x in parent_down_from_module(item)]))
        self.impl.start_case(name,
                             description=item.function.__doc__,
                             labels=labels_of(item))
        yield

        if not nextitem or parent_module(item) != parent_module(nextitem):
            self.impl.stop_suite()
            self.testsuite = None

    def pytest_runtest_logreport(self, report):
        if report.passed:
            if report.when == "call":  # ignore setup/teardown
                self._stop_case(report, status=Status.PASSED)
        elif report.failed:
            if report.when != "call":
                self._stop_case(report, status=Status.BROKEN)
            else:
                self._stop_case(report, status=Status.FAILED)
        elif report.skipped:
            if hasattr(report, 'wasxfail'):
                self._stop_case(report, status=Status.PENDING)
            else:
                self._stop_case(report, status=Status.CANCELED)

    @pytest.mark.hookwrapper
    def pytest_runtest_makereport(self, item, call):
        """
        That's the place we inject extra data into the report object from the actual Item.
        """
        report = yield
        report.get_result().__dict__.update(
            exception=call.excinfo,
            result=self.config.hook.pytest_report_teststatus(
                report=report.get_result())
            [0])  # get the failed/passed/xpassed thingy

    def pytest_sessionfinish(self):
        if self.testsuite:
            self.impl.stop_suite()
            self.testsuite = None
        self.impl.store_environment()
Ejemplo n.º 5
0
class AllureTestListener(object):
    """
    Listens to pytest hooks to generate reports for common tests.
    """
    def __init__(self, logdir, config):
        self.impl = AllureImpl(logdir)
        self.config = config

        # FIXME: maybe we should write explicit wrappers?
        self.attach = self.impl.attach
        self.start_step = self.impl.start_step
        self.stop_step = self.impl.stop_step

        self.testsuite = None

    def _stop_case(self, report, status=None):
        """
        Finalizes with important data the test at the top of ``self.stack`` and returns it
        """
        [self.attach(name, contents, AttachmentType.TEXT) for (name, contents) in dict(report.sections).items()]

        if status in FAILED_STATUSES:
            self.impl.stop_case(status,
                                message=get_exception_message(report),
                                trace=report.longrepr or report.wasxfail)
        elif status == Status.SKIPPED:
            # FIXME: see pytest.runner.pytest_runtest_makereport
            self.impl.stop_case(status,
                                message='skipped',
                                trace=type(report.longrepr) == tuple and report.longrepr[2] or report.wasxfail)
        else:
            self.impl.stop_case(status)

    def pytest_runtest_protocol(self, __multicall__, item, nextitem):
        if not self.testsuite:
            module = parent_module(item)

            self.impl.start_suite(name='.'.join(mangle_testnames(module.nodeid.split("::"))),
                                  description=module.module.__doc__ or None)
            self.testsuite = 'Yes'

        name = '.'.join(mangle_testnames([x.name for x in parent_down_from_module(item)]))

        self.impl.start_case(name, description=item.function.__doc__, severity=severity_of(item))

        result = __multicall__.execute()

        if not nextitem or parent_module(item) != parent_module(nextitem):
            self.impl.stop_suite()
            self.testsuite = None

        return result

    def pytest_runtest_logreport(self, report):
        if report.passed:
            if report.when == "call":  # ignore setup/teardown
                self._stop_case(report, status=Status.PASSED)
        elif report.failed:
            if report.when != "call":
                self._stop_case(report, status=Status.BROKEN)
            else:
                self._stop_case(report, status=Status.FAILED)
        elif report.skipped:
                self._stop_case(report, status=Status.SKIPPED)

    def pytest_runtest_makereport(self, item, call, __multicall__):  # @UnusedVariable
        """
        That's the place we inject extra data into the report object from the actual Item.
        """

        report = __multicall__.execute()
        report.__dict__.update(
            exception=call.excinfo,
            result=self.config.hook.pytest_report_teststatus(report=report)[0])  # get the failed/passed/xpassed thingy
        return report

    def pytest_sessionfinish(self):
        if self.testsuite:
            self.impl.stop_suite()
            self.testsuite = None