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
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'
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))
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))
def __init__(self, logdir): self.impl = AllureImpl(logdir) self.fails = []
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
def __init__(self, logdir): self.impl = AllureImpl(logdir)
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
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()
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
def allure_impl(reportdir): return AllureImpl(str(reportdir))
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