예제 #1
0
    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
예제 #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()
예제 #3
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()
def before_all(context):
    """
    Before all hook.
    Set config variables for whole run, setup logging, init allure.
    context.config.userdata is a dict with values from behave commandline.
    Example: -D foo=bar will store value in config.userdata['foo'].
    Will be executed once at the beginning of the test run.
    Context injected automatically by Behave.
    :type context: behave.runner.Context
    """
    if context.config.userdata:
        Config.BROWSER = context.config.userdata.get('browser',
                                                     Config.BROWSER).lower()
        Config.APP_URL = context.config.userdata.get('url',
                                                     Config.APP_URL).lower()
        Config.REUSE = context.config.userdata.get('reuse',
                                                   Config.REUSE).lower()
        Config.HIGHLIGHT = context.config.userdata.get(
            'highlight', Config.HIGHLIGHT).lower()

    Logger.configure_logging()
    logger = logging.getLogger(__name__)

    allure_report_path = '{}/allure_report'.format(Config.LOG_DIR)

    try:
        context.allure = AllureImpl(allure_report_path)
    except Exception:
        logger.error('Failed to init allure at: {}'.format(allure_report_path))
        raise
def pytest_configure(config):

    script_list = config.option.file_or_dir
    if script_list:
        _current_time = get_datentime()
        if CAFY_REPO:
            archive_name = 'allure'
            ARCHIVE = os.path.join(CafyLog.work_dir, archive_name)
            os.environ['ARCHIVE'] = ARCHIVE
            config.option.allurereportdir = ARCHIVE
            reportdir = config.option.allurereportdir

        if reportdir:  # we actually record something
            allure_impl = AllureImpl(reportdir)
            testlistener = AllureTestListener(config)
            pytest.allure._allurelistener = testlistener
            config.pluginmanager.register(testlistener)

        if not hasattr(config, 'slaveinput'):
            # on xdist-master node do all the important stuff
            config.pluginmanager.register(
                AllureAgregatingListener(allure_impl, config))
            config.pluginmanager.register(
                AllureCollectionListener(allure_impl))

        if config.option.no_allure:
            os.environ['NOALLURE'] = 'True'
예제 #6
0
def pytest_configure(config):
    pytest.allure = MASTER_HELPER

    for label in (Label.FEATURE, Label.STORY, Label.SEVERITY, Label.ISSUE,
                  Label.TESTCASE, Label.THREAD, Label.HOST, Label.FRAMEWORK,
                  Label.LANGUAGE):
        config.addinivalue_line(
            "markers",
            "%s.%s: this allure adaptor marker." % (Label.DEFAULT, label))

    reportdir = config.option.allurereportdir

    if reportdir:  # we actually record something
        allure_impl = AllureImpl(reportdir)

        testlistener = AllureTestListener(config)
        pytest.allure._allurelistener = testlistener
        config.pluginmanager.register(testlistener)

        if not hasattr(config, 'slaveinput'):
            # on xdist-master node do all the important stuff
            config.pluginmanager.register(
                AllureAgregatingListener(allure_impl, config))
            config.pluginmanager.register(
                AllureCollectionListener(allure_impl))
예제 #7
0
    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
예제 #8
0
def pytest_configure(config):
    reportdir = config.option.allurereportdir

    if reportdir:  # we actually record something
        allure_impl = AllureImpl(reportdir)

        testlistener = AllureTestListener(config)
        pytest.allure._allurelistener = testlistener
        config.pluginmanager.register(testlistener)

        if not hasattr(config, 'slaveinput'):
            # on xdist-master node do all the important stuff
            config.pluginmanager.register(AllureAgregatingListener(allure_impl, config))
            config.pluginmanager.register(AllureCollectionListener(allure_impl))
예제 #9
0
 def __init__(self, logdir):
     self.impl = AllureImpl(logdir)
     self.fails = []
예제 #10
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
예제 #11
0
 def __init__(self, logdir):
     self.impl = AllureImpl(logdir)
예제 #12
0
class AllureWrapper(object):
    def __init__(self, logdir):
        self.impl = AllureImpl(logdir)

    get_listener = lambda self: self.impl  # compatibility with pytest_plugin

    def attach(self, name, contents, type=AttachmentType.TEXT):
        self.impl.attach(name, contents, type)

    def step(self, title):
        """
        A contextmanager/decorator for steps.

        Usage examples::

          import nose

          def test_foo():
             with nose.allure.step('mystep'):
                 assert False

          @nose.allure.step('make test data')
          def make_test_data_bar():
              raise ValueError('No data today')

          def test_bar():
              assert make_test_data_bar()

          @nose.allure.step
          def make_test_data_baz():
              raise ValueError('No data today')

          def test_baz():
              assert make_test_data_baz()
        """
        if callable(title):
            return LazyInitStepContext(self, title.__name__)(title)
        else:
            return LazyInitStepContext(self, title)

    def label(self, name, value):
        return attr(**{'%s_%s' % (Label.DEFAULT, name): value})

    def severity(self, severity):
        return self.label(Label.SEVERITY, severity)

    def feature(self, feature):
        return self.label(Label.FEATURE, feature)

    def story(self, story):
        return self.label(Label.STORY, story)

    def issue(self, issue):
        return self.label(Label.ISSUE, issue)

    def environment(self, **env_dict):
        self.impl.environment.update(env_dict)

    @property
    def severity_level(self):
        return Severity
예제 #13
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()
예제 #14
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
예제 #15
0
def allure_impl(reportdir):
    return AllureImpl(str(reportdir))
예제 #16
0
class AllureWrapper(object):
    def __init__(self, logdir):
        self.impl = AllureImpl(logdir)

    get_listener = lambda self: self.impl  # compatibility with pytest_plugin

    def attach(self, name, contents, type=AttachmentType.TEXT):
        self.impl.attach(name, contents, type)

    def step(self, title):
        """
        A contextmanager/decorator for steps.

        Usage examples::

          import nose

          def test_foo():
             with nose.allure.step('mystep'):
                 assert False

          @nose.allure.step('make test data')
          def make_test_data_bar():
              raise ValueError('No data today')

          def test_bar():
              assert make_test_data_bar()

          @nose.allure.step
          def make_test_data_baz():
              raise ValueError('No data today')

          def test_baz():
              assert make_test_data_baz()
        """
        if callable(title):
            return LazyInitStepContext(self, title.__name__)(title)
        else:
            return LazyInitStepContext(self, title)

    def label(self, name, value):
        return attr(**{"%s_%s" % (Label.DEFAULT, name): value})

    def severity(self, severity):
        return self.label(Label.SEVERITY, severity)

    def feature(self, feature):
        return self.label(Label.FEATURE, feature)

    def story(self, story):
        return self.label(Label.STORY, story)

    def issue(self, issue):
        return self.label(Label.ISSUE, issue)

    def environment(self, **env_dict):
        self.impl.environment.update(env_dict)

    @property
    def severity_level(self):
        return Severity