diff --git a/.flake8 b/.flake8 deleted file mode 100644 index af25e839..00000000 --- a/.flake8 +++ /dev/null @@ -1,10 +0,0 @@ -[flake8] -max-line-length = 120 -import-order-style = google -inline-quotes = " -exclude = - ./tests/allure_behave/acceptance/**/test-data/** - ./tests/allure_behave/acceptance/behave_support/background/background_steps.py -per-file-ignores = - ./allure-python-commons/src/allure_commons/types.py:A005 - ./allure-robotframework/src/listener/types.py:A005 diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 03cda33b..83e7340c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -88,7 +88,7 @@ jobs: run: pip install -r ./requirements/linting.txt - name: Linting the codebase - run: poe linter + run: poe linter --output-format=github test-pytest: name: Test allure-pytest diff --git a/.gitignore b/.gitignore index 25e4deb0..7b7033cb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .tox .pytest_cache .python-version +.ruff_cache .venv *.pyc diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 7b6fd0ee..00000000 --- a/Jenkinsfile +++ /dev/null @@ -1,17 +0,0 @@ -pipeline { - agent { docker 'randomknowledge/docker-pyenv-tox' } - environment { - HOME = pwd() - } - stages { - stage("Build") { - steps { - sh 'tox -r --workdir=/tmp -c allure-python-commons-test/tox.ini' - sh 'tox -r --workdir=/tmp -c allure-python-commons/tox.ini' - sh 'tox -r --workdir=/tmp -c allure-pytest/tox.ini' - sh 'tox -r --workdir=/tmp -c allure-behave/tox.ini' - sh 'tox -r --workdir=/tmp -c allure-robotframework/tox.ini' - } - } - } -} diff --git a/allure-behave/pyproject.toml b/allure-behave/pyproject.toml index 388f9913..442ac2d8 100644 --- a/allure-behave/pyproject.toml +++ b/allure-behave/pyproject.toml @@ -1,5 +1,5 @@ [tool.poe.tasks] -linter = "flake8 --extend-ignore=A003 ./src" +linter = "ruff check" [tool.poe.tasks.tests] cmd = "pytest ../tests/allure_behave" diff --git a/allure-behave/setup.py b/allure-behave/setup.py index 9bb3dc41..4eefa3bc 100644 --- a/allure-behave/setup.py +++ b/allure-behave/setup.py @@ -4,20 +4,20 @@ PACKAGE = "allure-behave" classifiers = [ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Topic :: Software Development :: Quality Assurance', - 'Topic :: Software Development :: Testing', - 'Topic :: Software Development :: Testing :: BDD', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Topic :: Software Development :: Quality Assurance", + "Topic :: Software Development :: Testing", + "Topic :: Software Development :: Testing :: BDD", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] setup_requires = [ @@ -64,5 +64,5 @@ def main(): install_requires=install_requires ) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/allure-behave/src/formatter.py b/allure-behave/src/formatter.py index febd2d96..fd5576f1 100644 --- a/allure-behave/src/formatter.py +++ b/allure-behave/src/formatter.py @@ -24,7 +24,7 @@ def _wrap_scenario(self, scenarios): if isinstance(scenario, ScenarioOutline): self._wrap_scenario(scenario) else: - scenario.run = allure_commons.test(scenario.run, context={'scenario': scenario}) + scenario.run = allure_commons.test(scenario.run, context={"scenario": scenario}) is_planned_scenario(scenario, self.testplan) def uri(self, uri): diff --git a/allure-behave/src/hooks.py b/allure-behave/src/hooks.py index 7a153020..0873d94a 100644 --- a/allure-behave/src/hooks.py +++ b/allure-behave/src/hooks.py @@ -45,7 +45,7 @@ def __init__(self, result_dir): self.listener = AllureListener(Configuration()) self.plugins = [] - if not hasattr(_storage, 'file_logger'): + if not hasattr(_storage, "file_logger"): logger = AllureFileLogger(result_dir) _storage.file_logger = logger allure_commons.plugin_manager.register(logger) diff --git a/allure-behave/src/listener.py b/allure-behave/src/listener.py index e7f9be8a..c584f6b5 100644 --- a/allure-behave/src/listener.py +++ b/allure-behave/src/listener.py @@ -29,9 +29,9 @@ class AllureListener: 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.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 @@ -70,7 +70,7 @@ def stop_feature(self): @allure_commons.hookimpl def start_test(self, parent_uuid, uuid, name, parameters, context): - self.start_scenario(context['scenario']) + self.start_scenario(context["scenario"]) def start_scenario(self, scenario): self.current_scenario_uuid = uuid4() @@ -82,7 +82,7 @@ def start_scenario(self, scenario): test_case.titlePath = get_title_path(scenario) test_case.historyId = scenario_history_id(scenario) test_case.testCaseId = md5(test_case.fullName) - test_case.description = '\n'.join(scenario.description) + test_case.description = "\n".join(scenario.description) test_case.parameters = scenario_parameters(scenario) test_case.links.extend(scenario_links( @@ -91,20 +91,20 @@ def start_scenario(self, scenario): 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.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']) + self.stop_scenario(context["scenario"]) def stop_scenario(self, scenario): tag_expression = self.__get_tag_expression(self.behave_config) should_run = scenario.should_run_with_tags(tag_expression) should_run = should_run 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_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: @@ -135,16 +135,16 @@ def match_step(self, match): def start_behave_step(self, step): self.current_step_uuid = uuid4() - name = f'{step.keyword} {step.name}' + name = f"{step.keyword} {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) + 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) + self.logger.attach_data(uuid4(), step_table(step), name=".table", attachment_type=AttachmentType.CSV) def stop_behave_step(self, result): status = step_status(result) @@ -194,7 +194,7 @@ def add_description_html(self, test_description_html): def add_link(self, url, link_type, name): test_result = self.logger.get_test(None) if test_result: - pattern = '{}' + pattern = "{}" if link_type == LinkType.ISSUE and self.issue_pattern: pattern = self.issue_pattern elif link_type == LinkType.LINK and self.link_pattern: @@ -230,7 +230,7 @@ def enter(self): self._logger.start_group(group.uuid, group) self._groups.append(group) - def exit(self): # noqa: A003 + def exit(self): group = self._groups.pop() if group.befores or group.afters: self._logger.stop_group(group.uuid) diff --git a/allure-behave/src/utils.py b/allure-behave/src/utils.py index ce0f2d70..da5cf073 100644 --- a/allure-behave/src/utils.py +++ b/allure-behave/src/utils.py @@ -14,11 +14,11 @@ TEST_PLAN_SKIP_REASON = "Not in allure test plan" STATUS = { - 'passed': Status.PASSED, - 'failed': Status.FAILED, - 'skipped': Status.SKIPPED, - 'untested': Status.SKIPPED, - 'undefined': Status.BROKEN + "passed": Status.PASSED, + "failed": Status.FAILED, + "skipped": Status.SKIPPED, + "untested": Status.SKIPPED, + "undefined": Status.BROKEN } @@ -30,7 +30,7 @@ def scenario_history_id(scenario): parts = [scenario.feature.name, scenario.name] if scenario._row: row = scenario._row - parts.extend([f'{name}={value}' for name, value in zip(row.headings, row.cells)]) + parts.extend([f"{name}={value}" for name, value in zip(row.headings, row.cells)]) return md5(*parts) @@ -57,14 +57,14 @@ def scenario_labels(scenario): def scenario_status(scenario): for step in scenario.all_steps: - if step_status(step) != 'passed': + if step_status(step) != "passed": return step_status(step) return Status.PASSED def scenario_status_details(scenario): for step in scenario.all_steps: - if step_status(step) != 'passed': + if step_status(step) != "passed": return step_status_details(step) @@ -151,8 +151,8 @@ def step_status_details(result): trace=trace ) - elif result.status == 'undefined': - message = '\nYou can implement step definitions for undefined steps with these snippets:\n\n' + elif result.status == "undefined": + message = "\nYou can implement step definitions for undefined steps with these snippets:\n\n" message += make_undefined_step_snippet(result) return StatusDetails(message=message) diff --git a/allure-nose2/pyproject.toml b/allure-nose2/pyproject.toml index 822f5d98..a411cd33 100644 --- a/allure-nose2/pyproject.toml +++ b/allure-nose2/pyproject.toml @@ -1,5 +1,5 @@ [tool.poe.tasks] -linter = "flake8 ./src" +linter = "ruff check" [tool.poe.tasks.tests] cmd = "pytest ../tests/allure_nose2" diff --git a/allure-nose2/setup.py b/allure-nose2/setup.py index 6f7a1ec5..4d03ddbc 100644 --- a/allure-nose2/setup.py +++ b/allure-nose2/setup.py @@ -4,19 +4,19 @@ PACKAGE = "allure-nose2" classifiers = [ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Topic :: Software Development :: Quality Assurance', - 'Topic :: Software Development :: Testing', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Topic :: Software Development :: Quality Assurance", + "Topic :: Software Development :: Testing", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] setup_requires = [ @@ -63,5 +63,5 @@ def main(): ) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/allure-nose2/src/plugin.py b/allure-nose2/src/plugin.py index 678fe8f1..edd4d65d 100644 --- a/allure-nose2/src/plugin.py +++ b/allure-nose2/src/plugin.py @@ -44,7 +44,7 @@ def unregister(cls): class Allure(Plugin): - configSection = 'allure' + configSection = "allure" commandLineSwitch = (None, "allure", "Generate an Allure report") def __init__(self, *args, **kwargs): @@ -95,7 +95,7 @@ def startTest(self, event): test_result.labels.extend(labels(event.test)) 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='nose2')) + test_result.labels.append(Label(name=LabelType.FRAMEWORK, value="nose2")) test_result.labels.append(Label(name=LabelType.LANGUAGE, value=platform_label())) test_result.parameters = params(event) diff --git a/allure-nose2/src/utils.py b/allure-nose2/src/utils.py index 4e2e885d..23e83d23 100644 --- a/allure-nose2/src/utils.py +++ b/allure-nose2/src/utils.py @@ -7,9 +7,9 @@ # ToDo move to commons ALLURE_LABELS = [ - 'epic', - 'feature', - 'story', + "epic", + "feature", + "story", ] @@ -21,8 +21,8 @@ def status_details(event): message, trace = None, None if event.exc_info: exc_type, value, _ = event.exc_info - message = '\n'.join(format_exception_only(exc_type, value)) if exc_type or value else None - trace = ''.join(util.exc_info_to_string(event.exc_info, event.test)) + message = "\n".join(format_exception_only(exc_type, value)) if exc_type or value else None + trace = "".join(util.exc_info_to_string(event.exc_info, event.test)) elif event.reason: message = event.reason diff --git a/allure-pytest-bdd/pyproject.toml b/allure-pytest-bdd/pyproject.toml index 83277cf5..ec703429 100644 --- a/allure-pytest-bdd/pyproject.toml +++ b/allure-pytest-bdd/pyproject.toml @@ -1,5 +1,5 @@ [tool.poe.tasks] -linter = "flake8 ./src" +linter = "ruff check" [tool.poe.tasks.tests] cmd = "pytest ../tests/allure_pytest_bdd" diff --git a/allure-pytest-bdd/setup.py b/allure-pytest-bdd/setup.py index 4e651458..4c77133a 100644 --- a/allure-pytest-bdd/setup.py +++ b/allure-pytest-bdd/setup.py @@ -4,21 +4,21 @@ PACKAGE = "allure-pytest-bdd" classifiers = [ - 'Development Status :: 5 - Production/Stable', - 'Framework :: Pytest', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Topic :: Software Development :: Quality Assurance', - 'Topic :: Software Development :: Testing', - 'Topic :: Software Development :: Testing :: BDD', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', + "Development Status :: 5 - Production/Stable", + "Framework :: Pytest", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Topic :: Software Development :: Quality Assurance", + "Topic :: Software Development :: Testing", + "Topic :: Software Development :: Testing :: BDD", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] setup_requires = [ @@ -67,5 +67,5 @@ def main(): ) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/allure-pytest-bdd/src/plugin.py b/allure-pytest-bdd/src/plugin.py index 521eadc4..0579c66e 100644 --- a/allure-pytest-bdd/src/plugin.py +++ b/allure-pytest-bdd/src/plugin.py @@ -15,20 +15,20 @@ def pytest_addoption(parser): - parser.getgroup("reporting").addoption('--alluredir', + parser.getgroup("reporting").addoption("--alluredir", action="store", dest="allure_report_dir", metavar="DIR", default=None, help="Generate Allure report in the specified directory (may not exist)") - parser.getgroup("reporting").addoption('--clean-alluredir', + parser.getgroup("reporting").addoption("--clean-alluredir", action="store_true", dest="clean_alluredir", help="Clean alluredir folder if it exists") def link_pattern(string): - pattern = string.split(':', 1) + pattern = string.split(":", 1) if not pattern[0]: raise argparse.ArgumentTypeError("A link type is mandatory") diff --git a/allure-pytest-bdd/src/pytest_bdd_listener.py b/allure-pytest-bdd/src/pytest_bdd_listener.py index bcc6cba0..f91e34ae 100644 --- a/allure-pytest-bdd/src/pytest_bdd_listener.py +++ b/allure-pytest-bdd/src/pytest_bdd_listener.py @@ -141,5 +141,5 @@ def pytest_runtest_makereport(self, item, call): attach_data(self.lifecycle, report.capstderr, "stderr", AttachmentType.TEXT, None) post_process_test_result(item, test_result) - if report.when == 'teardown': + if report.when == "teardown": self.lifecycle.write_test_case(uuid=uuid) diff --git a/allure-pytest-bdd/src/utils.py b/allure-pytest-bdd/src/utils.py index f4a838b1..609a1509 100644 --- a/allure-pytest-bdd/src/utils.py +++ b/allure-pytest-bdd/src/utils.py @@ -27,8 +27,8 @@ ALLURE_TITLE_ATTR = "__allure_display_name__" ALLURE_DESCRIPTION_MARK = "allure_description" ALLURE_DESCRIPTION_HTML_MARK = "allure_description_html" -ALLURE_LABEL_MARK = 'allure_label' -ALLURE_LINK_MARK = 'allure_link' +ALLURE_LABEL_MARK = "allure_label" +ALLURE_LINK_MARK = "allure_link" MARK_NAMES_TO_IGNORE = { "usefixtures", @@ -236,13 +236,13 @@ def get_scenario_status_details(report, excinfo): def get_outline_params(node): - if hasattr(node, 'callspec'): - return node.callspec.params.get('_pytest_bdd_example', {}) + if hasattr(node, "callspec"): + return node.callspec.params.get("_pytest_bdd_example", {}) return {} def get_pytest_params(node): - if hasattr(node, 'callspec'): + if hasattr(node, "callspec"): pytest_params = dict(node.callspec.params) if "_pytest_bdd_example" in pytest_params: del pytest_params["_pytest_bdd_example"] diff --git a/allure-pytest/pyproject.toml b/allure-pytest/pyproject.toml index 22458017..98187503 100644 --- a/allure-pytest/pyproject.toml +++ b/allure-pytest/pyproject.toml @@ -1,5 +1,5 @@ [tool.poe.tasks] -linter = "flake8 ./src" +linter = "ruff check" [tool.poe.tasks.tests] cmd = "pytest ../tests/allure_pytest" diff --git a/allure-pytest/setup.py b/allure-pytest/setup.py index 6597abf5..de5ea954 100644 --- a/allure-pytest/setup.py +++ b/allure-pytest/setup.py @@ -1,9 +1,10 @@ -import os,sys +import os +import sys from setuptools import setup from pkg_resources import require, DistributionNotFound, VersionConflict try: - require('pytest-allure-adaptor') + require("pytest-allure-adaptor") print(""" You have pytest-allure-adaptor installed. You need to remove pytest-allure-adaptor from your site-packages @@ -16,20 +17,20 @@ PACKAGE = "allure-pytest" classifiers = [ - 'Development Status :: 5 - Production/Stable', - 'Framework :: Pytest', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Topic :: Software Development :: Quality Assurance', - 'Topic :: Software Development :: Testing', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', + "Development Status :: 5 - Production/Stable", + "Framework :: Pytest", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Topic :: Software Development :: Quality Assurance", + "Topic :: Software Development :: Testing", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] setup_requires = [ @@ -78,5 +79,5 @@ def main(): install_requires=install_requires ) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/allure-pytest/src/listener.py b/allure-pytest/src/listener.py index 42b7ff49..21c06750 100644 --- a/allure-pytest/src/listener.py +++ b/allure-pytest/src/listener.py @@ -149,14 +149,14 @@ def pytest_runtest_teardown(self, item): self.__apply_default_suites(item, test_result) 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.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.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 = getattr(fixturedef.func, '__allure_display_name__', fixturedef.argname) + fixture_name = getattr(fixturedef.func, "__allure_display_name__", fixturedef.argname) container_uuid = self._cache.get(fixturedef) @@ -178,16 +178,16 @@ def pytest_fixture_setup(self, fixturedef, request): status=get_outcome_status(outcome), statusDetails=get_outcome_status_details(outcome)) - finalizers = getattr(fixturedef, '_finalizers', []) + finalizers = getattr(fixturedef, "_finalizers", []) for index, finalizer in enumerate(finalizers): finalizer_name = getattr(finalizer, "__name__", index) - name = f'{fixture_name}::{finalizer_name}' + name = f"{fixture_name}::{finalizer_name}" 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): + 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()) @@ -203,9 +203,9 @@ def pytest_runtest_makereport(self, item, call): if call.excinfo: message = call.excinfo.exconly() - if hasattr(report, 'wasxfail'): + if hasattr(report, "wasxfail"): reason = report.wasxfail - message = (f'XFAIL {reason}' if reason else 'XFAIL') + '\n\n' + message + message = (f"XFAIL {reason}" if reason else "XFAIL") + "\n\n" + message trace = report.longreprtext status_details = StatusDetails( message=message, @@ -215,21 +215,21 @@ def pytest_runtest_makereport(self, item, call): if (status != Status.SKIPPED and _exception_brokes_test(exception)): status = Status.BROKEN - if status == Status.PASSED and hasattr(report, 'wasxfail'): + if status == Status.PASSED and hasattr(report, "wasxfail"): reason = report.wasxfail - message = f'XPASS {reason}' if reason else 'XPASS' + message = f"XPASS {reason}" if reason else "XPASS" status_details = StatusDetails(message=message) - if report.when == 'setup': + if report.when == "setup": test_result.status = status test_result.statusDetails = status_details - if report.when == 'call': + if report.when == "call": if test_result.status == Status.PASSED: test_result.status = status test_result.statusDetails = status_details - if report.when == 'teardown': + 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 @@ -310,11 +310,11 @@ def add_parameter(self, name, value, excluded, mode: ParameterMode): @staticmethod def __get_pytest_params(item): - return item.callspec.params if hasattr(item, 'callspec') else {} + return item.callspec.params if hasattr(item, "callspec") else {} @staticmethod def __get_pytest_param_id(item): - return item.callspec.id if hasattr(item, 'callspec') else None + return item.callspec.id if hasattr(item, "callspec") else None def __apply_default_suites(self, item, test_result): default_suites = allure_suite_labels(item) diff --git a/allure-pytest/src/plugin.py b/allure-pytest/src/plugin.py index 2771722f..9efc358b 100644 --- a/allure-pytest/src/plugin.py +++ b/allure-pytest/src/plugin.py @@ -17,24 +17,24 @@ def pytest_addoption(parser): - parser.getgroup("reporting").addoption('--alluredir', + parser.getgroup("reporting").addoption("--alluredir", action="store", dest="allure_report_dir", metavar="DIR", default=None, help="Generate Allure report in the specified directory (may not exist)") - parser.getgroup("reporting").addoption('--clean-alluredir', + parser.getgroup("reporting").addoption("--clean-alluredir", action="store_true", dest="clean_alluredir", help="Clean alluredir folder if it exists") - parser.getgroup("reporting").addoption('--allure-no-capture', + parser.getgroup("reporting").addoption("--allure-no-capture", action="store_false", dest="attach_capture", help="Do not attach pytest captured logging/stdout/stderr to report") - parser.getgroup("reporting").addoption('--inversion', + parser.getgroup("reporting").addoption("--inversion", action="store", dest="inversion", default=False, @@ -42,21 +42,21 @@ def pytest_addoption(parser): def label_type(type_name, legal_values=set()): def a_label_type(string): - atoms = set(string.split(',')) + atoms = set(string.split(",")) if type_name is LabelType.SEVERITY: if not atoms <= legal_values: - raise argparse.ArgumentTypeError('Illegal {} values: {}, only [{}] are allowed'.format( + raise argparse.ArgumentTypeError("Illegal {} values: {}, only [{}] are allowed".format( type_name, - ', '.join(atoms - legal_values), - ', '.join(legal_values) + ", ".join(atoms - legal_values), + ", ".join(legal_values) )) return set((type_name, allure.severity_level(atom)) for atom in atoms) return set((type_name, atom) for atom in atoms) return a_label_type severities = [x.value for x in list(allure.severity_level)] - formatted_severities = ', '.join(severities) - parser.getgroup("general").addoption('--allure-severities', + formatted_severities = ", ".join(severities) + parser.getgroup("general").addoption("--allure-severities", action="store", dest="allure_severities", metavar="SEVERITIES_SET", @@ -66,7 +66,7 @@ def a_label_type(string): Tests only with these severities will be run. Possible values are: {formatted_severities}.""") - parser.getgroup("general").addoption('--allure-epics', + parser.getgroup("general").addoption("--allure-epics", action="store", dest="allure_epics", metavar="EPICS_SET", @@ -75,7 +75,7 @@ def a_label_type(string): help="""Comma-separated list of epic names. Run tests that have at least one of the specified feature labels.""") - parser.getgroup("general").addoption('--allure-features', + parser.getgroup("general").addoption("--allure-features", action="store", dest="allure_features", metavar="FEATURES_SET", @@ -84,7 +84,7 @@ def a_label_type(string): help="""Comma-separated list of feature names. Run tests that have at least one of the specified feature labels.""") - parser.getgroup("general").addoption('--allure-stories', + parser.getgroup("general").addoption("--allure-stories", action="store", dest="allure_stories", metavar="STORIES_SET", @@ -93,7 +93,7 @@ def a_label_type(string): help="""Comma-separated list of story names. Run tests that have at least one of the specified story labels.""") - parser.getgroup("general").addoption('--allure-ids', + parser.getgroup("general").addoption("--allure-ids", action="store", dest="allure_ids", metavar="IDS_SET", @@ -107,7 +107,7 @@ def cf_type(string): atoms = set(values.split(",")) return [(type_name, atom) for atom in atoms] - parser.getgroup("general").addoption('--allure-label', + parser.getgroup("general").addoption("--allure-label", action="append", dest="allure_labels", metavar="LABELS_SET", @@ -117,15 +117,15 @@ def cf_type(string): "Run tests that have at least one of the specified labels.""") def link_pattern(string): - pattern = string.split(':', 1) + pattern = string.split(":", 1) if not pattern[0]: - raise argparse.ArgumentTypeError('Link type is mandatory.') + raise argparse.ArgumentTypeError("Link type is mandatory.") if len(pattern) != 2: - raise argparse.ArgumentTypeError('Link pattern is mandatory') + raise argparse.ArgumentTypeError("Link pattern is mandatory") return pattern - parser.getgroup("general").addoption('--allure-link-pattern', + parser.getgroup("general").addoption("--allure-link-pattern", action="append", dest="allure_link_pattern", metavar="LINK_TYPE:LINK_PATTERN", @@ -160,7 +160,7 @@ def pytest_configure(config): if report_dir: report_dir = os.path.abspath(report_dir) test_listener = AllureListener(config) - config.pluginmanager.register(test_listener, 'allure_listener') + config.pluginmanager.register(test_listener, "allure_listener") allure_commons.plugin_manager.register(test_listener) config.add_cleanup(cleanup_factory(test_listener)) diff --git a/allure-pytest/src/stash.py b/allure-pytest/src/stash.py index 31d9302b..83e31b57 100644 --- a/allure-pytest/src/stash.py +++ b/allure-pytest/src/stash.py @@ -1,7 +1,7 @@ import pytest from functools import wraps -HAS_STASH = hasattr(pytest, 'StashKey') +HAS_STASH = hasattr(pytest, "StashKey") def create_stashkey_safe(): diff --git a/allure-pytest/src/utils.py b/allure-pytest/src/utils.py index 56594a09..31ffb63f 100644 --- a/allure-pytest/src/utils.py +++ b/allure-pytest/src/utils.py @@ -7,10 +7,10 @@ from allure_commons.types import LabelType from allure_pytest.stash import stashed -ALLURE_DESCRIPTION_MARK = 'allure_description' -ALLURE_DESCRIPTION_HTML_MARK = 'allure_description_html' -ALLURE_LABEL_MARK = 'allure_label' -ALLURE_LINK_MARK = 'allure_link' +ALLURE_DESCRIPTION_MARK = "allure_description" +ALLURE_DESCRIPTION_HTML_MARK = "allure_description_html" +ALLURE_LABEL_MARK = "allure_label" +ALLURE_LINK_MARK = "allure_link" ALLURE_UNIQUE_LABELS = [ LabelType.SEVERITY, LabelType.FRAMEWORK, @@ -34,11 +34,11 @@ class ParsedPytestNodeId: def __init__(self, nodeid): filepath, *class_names, function_segment = ensure_len(nodeid.split("::"), 2) self.filepath = filepath - self.path_segments = filepath.split('/') + self.path_segments = filepath.split("/") *parent_dirs, filename = ensure_len(self.path_segments, 1) - self.parent_package = '.'.join(parent_dirs) + self.parent_package = ".".join(parent_dirs) self.module = filename.rsplit(".", 1)[0] - self.package = '.'.join(filter(None, [self.parent_package, self.module])) + self.package = ".".join(filter(None, [self.parent_package, self.module])) self.class_names = class_names self.test_function = function_segment.split("[", 1)[0] @@ -65,7 +65,7 @@ def allure_description(item): description = get_marker_value(item, ALLURE_DESCRIPTION_MARK) if description: return description - elif hasattr(item, 'function'): + elif hasattr(item, "function"): return item.function.__doc__ @@ -103,7 +103,7 @@ def allure_links(item): def format_allure_link(config, url, link_type): - pattern = dict(config.option.allure_link_pattern).get(link_type, '{}') + pattern = dict(config.option.allure_link_pattern).get(link_type, "{}") return pattern.format(url) @@ -203,7 +203,7 @@ def get_status_details(exception_type, exception, exception_traceback): def get_pytest_report_status(pytest_report): - pytest_statuses = ('failed', 'passed', 'skipped') + pytest_statuses = ("failed", "passed", "skipped") statuses = (Status.FAILED, Status.PASSED, Status.SKIPPED) for pytest_status, status in zip(pytest_statuses, statuses): if getattr(pytest_report, pytest_status): diff --git a/allure-python-commons-test/pyproject.toml b/allure-python-commons-test/pyproject.toml index cc2b9ab5..a817d869 100644 --- a/allure-python-commons-test/pyproject.toml +++ b/allure-python-commons-test/pyproject.toml @@ -1,3 +1,3 @@ [tool.poe.tasks] -linter = "flake8 ./src" +linter = "ruff check" tests = "python -m doctest ./src/*.py" diff --git a/allure-python-commons-test/setup.py b/allure-python-commons-test/setup.py index bfcaddca..8b7c3266 100644 --- a/allure-python-commons-test/setup.py +++ b/allure-python-commons-test/setup.py @@ -4,19 +4,19 @@ PACKAGE = "allure-python-commons-test" classifiers = [ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Topic :: Software Development :: Quality Assurance', - 'Topic :: Software Development :: Testing', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Topic :: Software Development :: Quality Assurance", + "Topic :: Software Development :: Testing", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] install_requires = [ @@ -32,7 +32,7 @@ def main(): setup( name=PACKAGE, use_scm_version={"root": "..", "relative_to": __file__}, - setup_requires=['setuptools_scm'], + setup_requires=["setuptools_scm"], description=( "A collection of PyHamcrest matchers to test Allure adapters for " "Python test frameworks" @@ -53,5 +53,5 @@ def main(): install_requires=install_requires ) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/allure-python-commons-test/src/container.py b/allure-python-commons-test/src/container.py index 50aa1e6b..382c2502 100644 --- a/allure-python-commons-test/src/container.py +++ b/allure-python-commons-test/src/container.py @@ -11,16 +11,16 @@ def __init__(self, report, *matchers): def _matches(self, item): return has_property( - 'test_containers', + "test_containers", has_item( all_of( - has_entry('children', has_item(item['uuid'])), + has_entry("children", has_item(item["uuid"])), *self.matchers ) )).matches(self.report) def describe_to(self, description): - description.append_text('describe me later').append_list('[', ', ', ']', self.matchers) + description.append_text("describe me later").append_list("[", ", ", "]", self.matchers) def describe_mismatch(self, item, mismatch_description): self.matches(item, mismatch_description) @@ -84,14 +84,14 @@ def __init__(self, *args): @staticmethod def _test_case_id_by_name(report, test_case_name): for test_case in report.test_cases: - if test_case['fullName'].endswith(test_case_name): - return test_case['uuid'] + if test_case["fullName"].endswith(test_case_name): + return test_case["uuid"] def _matches(self, report): - return has_property('test_containers', + return has_property("test_containers", has_item( all_of( - has_entry('children', + has_entry("children", all_of( *[has_item(self._test_case_id_by_name(report, name)) for name in self.test_case_names] @@ -103,7 +103,7 @@ def _matches(self, report): # TODO better describe def describe_to(self, description): - description.append_text('test_case has group') + description.append_text("test_case has group") def has_same_container(*args): @@ -156,7 +156,7 @@ def has_fixture(section, name, *matchers): section, has_item( all_of( - has_entry('name', equal_to(name)), + has_entry("name", equal_to(name)), *matchers ) ) @@ -164,8 +164,8 @@ def has_fixture(section, name, *matchers): def has_before(name, *matchers): - return has_fixture('befores', name, *matchers) + return has_fixture("befores", name, *matchers) def has_after(name, *matchers): - return has_fixture('afters', name, *matchers) + return has_fixture("afters", name, *matchers) diff --git a/allure-python-commons-test/src/label.py b/allure-python-commons-test/src/label.py index 15d9e3d2..364d43a1 100644 --- a/allure-python-commons-test/src/label.py +++ b/allure-python-commons-test/src/label.py @@ -7,55 +7,55 @@ def has_label(name, value=None): if value is None: value = anything() return has_entry( - 'labels', + "labels", has_item( all_of( - has_entry('name', name), - has_entry('value', value) + has_entry("name", name), + has_entry("value", value) ) ) ) def has_severity(level): - return has_label('severity', level) + return has_label("severity", level) def has_epic(feature): - return has_label('epic', feature) + return has_label("epic", feature) def has_feature(feature): - return has_label('feature', feature) + return has_label("feature", feature) def has_story(story): - return has_label('story', story) + return has_label("story", story) def has_tag(tag): - return has_label('tag', tag) + return has_label("tag", tag) def has_package(package): - return has_label('package', package) + return has_label("package", package) def has_suite(suite): - return has_label('suite', suite) + return has_label("suite", suite) def has_parent_suite(parent_suite): - return has_label('parentSuite', parent_suite) + return has_label("parentSuite", parent_suite) def has_sub_suite(sub_suite): - return has_label('subSuite', sub_suite) + return has_label("subSuite", sub_suite) def has_allure_id(allure_id): - return has_label('as_id', allure_id) + return has_label("as_id", allure_id) def has_manual(allure_id): - return has_label('ALLURE_MANUAL', allure_id) + return has_label("ALLURE_MANUAL", allure_id) diff --git a/allure-python-commons-test/src/report.py b/allure-python-commons-test/src/report.py index 82036ea3..70e8b637 100644 --- a/allure-python-commons-test/src/report.py +++ b/allure-python-commons-test/src/report.py @@ -84,19 +84,19 @@ def __init__(self, result): self.test_cases = [ json.load(file) for _, file in self._report_items( result, - '*result.json' + "*result.json" ) ] self.test_containers = [ json.load(file) for _, file in self._report_items( result, - '*container.json' + "*container.json" ) ] self.attachments = { name: file.read() for name, file in self._report_items( result, - '*attachment.*' + "*attachment.*" ) } @@ -111,12 +111,12 @@ def _report_items(report_dir, glob): def has_test_case(name, *matchers): return has_property( - 'test_cases', + "test_cases", has_item( all_of( any_of( - has_entry('fullName', ends_with(name)), - has_entry('name', starts_with(name)) + has_entry("fullName", ends_with(name)), + has_entry("name", starts_with(name)) ), *matchers ) @@ -129,7 +129,7 @@ def __init__(self, *matchers): self.matchers = matchers def _matches(self, item): - return has_property('test_cases', + return has_property("test_cases", only_contains(any_of(*self.matchers)) ).matches(item) @@ -160,19 +160,19 @@ def _matches(self, item): def describe_to(self, description): description.append_text( - f'exactly {self.num} item(s) matching ' + f"exactly {self.num} item(s) matching " ).append_text(self.matcher) def has_only_n_test_cases(name, num, *matchers): return has_property( - 'test_cases', + "test_cases", ContainsExactly( num, all_of( any_of( - has_entry('fullName', ends_with(name)), - has_entry('name', ends_with(name)) + has_entry("fullName", ends_with(name)), + has_entry("name", ends_with(name)) ), *matchers ) diff --git a/allure-python-commons-test/src/result.py b/allure-python-commons-test/src/result.py index fb83000c..97803d21 100644 --- a/allure-python-commons-test/src/result.py +++ b/allure-python-commons-test/src/result.py @@ -71,7 +71,7 @@ def has_title(title): - return has_entry('name', title) + return has_entry("name", title) def has_title_path(*matchers): @@ -82,19 +82,19 @@ def has_title_path(*matchers): def has_description(*matchers): - return has_entry('description', all_of(*matchers)) + return has_entry("description", all_of(*matchers)) def has_description_html(*matchers): - return has_entry('descriptionHtml', all_of(*matchers)) + return has_entry("descriptionHtml", all_of(*matchers)) def has_step(name, *matchers): return has_entry( - 'steps', + "steps", has_item( all_of( - has_entry('name', equal_to(name)), + has_entry("name", equal_to(name)), *matchers ) ) @@ -110,10 +110,10 @@ def with_steps(*matchers): def get_parameter_matcher(name, *matchers): return has_entry( - 'parameters', + "parameters", has_item( all_of( - has_entry('name', equal_to(name)), + has_entry("name", equal_to(name)), *matchers ) ) @@ -123,7 +123,7 @@ def get_parameter_matcher(name, *matchers): def has_parameter(name, value, *matchers): return get_parameter_matcher( name, - has_entry('value', equal_to(value)), + has_entry("value", equal_to(value)), *matchers ) @@ -148,12 +148,12 @@ def resolve_link_attr_matcher(key, value): def has_link(url, link_type=None, name=None): return has_entry( - 'links', + "links", has_item( all_of( *[ resolve_link_attr_matcher(key, value) for key, value in zip( - ('url', 'type', 'name'), + ("url", "type", "name"), (url, link_type, name) ) if value is not None ] @@ -163,21 +163,21 @@ def has_link(url, link_type=None, name=None): def has_issue_link(url, name=None): - return has_link(url, link_type='issue', name=name) + return has_link(url, link_type="issue", name=name) def has_test_case_link(url, name=None): - return has_link(url, link_type='tms', name=name) + return has_link(url, link_type="tms", name=name) def has_attachment(attach_type=None, name=None): return has_entry( - 'attachments', + "attachments", has_item( all_of( - has_entry('source', anything()), - has_entry('type', attach_type) if attach_type else anything(), - has_entry('name', name) if name else anything() + has_entry("source", anything()), + has_entry("type", attach_type) if attach_type else anything(), + has_entry("name", name) if name else anything() ) ) ) @@ -190,51 +190,51 @@ def has_attachment_with_content( name=None ): return has_entry( - 'attachments', + "attachments", has_item( all_of( - has_entry('name', name) if name else anything(), - has_entry('type', attach_type) if attach_type else anything(), - has_entry('source', maps_to(attachments, content_matcher)) + has_entry("name", name) if name else anything(), + has_entry("type", attach_type) if attach_type else anything(), + has_entry("source", maps_to(attachments, content_matcher)) ) ) ) def with_id(): - return has_entry('uuid', not_none()) + return has_entry("uuid", not_none()) def with_status(status): - return has_entry('status', status) + return has_entry("status", status) def has_status_details(*matchers): - return has_entry('statusDetails', all_of(*matchers)) + return has_entry("statusDetails", all_of(*matchers)) def with_message_contains(string): - return has_entry('message', contains_string(string)) + return has_entry("message", contains_string(string)) def with_trace_contains(string): - return has_entry('trace', contains_string(string)) + return has_entry("trace", contains_string(string)) def with_excluded(): - return has_entry('excluded', True) + return has_entry("excluded", True) def with_mode(mode): - return has_entry('mode', mode) + return has_entry("mode", mode) def has_history_id(matcher=None): - return has_entry('historyId', matcher or anything()) + return has_entry("historyId", matcher or anything()) def has_test_case_id(matcher=None): - return has_entry('testCaseId', matcher or anything()) + return has_entry("testCaseId", matcher or anything()) def has_full_name(matcher): diff --git a/allure-python-commons/pyproject.toml b/allure-python-commons/pyproject.toml index 9fd4df26..3111b705 100644 --- a/allure-python-commons/pyproject.toml +++ b/allure-python-commons/pyproject.toml @@ -1,3 +1,3 @@ [tool.poe.tasks] -linter = "flake8 --extend-ignore=A001,A002,A003 ./src" +linter = "ruff check" tests = "python -m doctest ./src/allure_commons/*.py" diff --git a/allure-python-commons/src/allure/__init__.py b/allure-python-commons/src/allure/__init__.py index c30329a6..4e72e402 100644 --- a/allure-python-commons/src/allure/__init__.py +++ b/allure-python-commons/src/allure/__init__.py @@ -17,27 +17,27 @@ __all__ = [ - 'title', - 'description', - 'description_html', - 'label', - 'severity', - 'suite', - 'parent_suite', - 'sub_suite', - 'tag', - 'id', - 'epic', - 'feature', - 'story', - 'link', - 'issue', - 'testcase', - 'manual', - 'step', - 'dynamic', - 'severity_level', - 'attach', - 'attachment_type', - 'parameter_mode' + "title", + "description", + "description_html", + "label", + "severity", + "suite", + "parent_suite", + "sub_suite", + "tag", + "id", + "epic", + "feature", + "story", + "link", + "issue", + "testcase", + "manual", + "step", + "dynamic", + "severity_level", + "attach", + "attachment_type", + "parameter_mode" ] diff --git a/allure-python-commons/src/allure_commons/__init__.py b/allure-python-commons/src/allure_commons/__init__.py index 111c2d06..e480acea 100644 --- a/allure-python-commons/src/allure_commons/__init__.py +++ b/allure-python-commons/src/allure_commons/__init__.py @@ -1,12 +1,12 @@ -from allure_commons._hooks import hookimpl # noqa: F401 -from allure_commons._core import plugin_manager # noqa: F401 -from allure_commons._allure import fixture # noqa: F401 -from allure_commons._allure import test # noqa: F401 +from allure_commons._hooks import hookimpl +from allure_commons._core import plugin_manager +from allure_commons._allure import fixture +from allure_commons._allure import test __all__ = [ - 'hookimpl', - 'plugin_manager', - 'fixture', - 'test' + "hookimpl", + "plugin_manager", + "fixture", + "test" ] diff --git a/allure-python-commons/src/allure_commons/_allure.py b/allure-python-commons/src/allure_commons/_allure.py index b7bbe2a5..08fb5a87 100644 --- a/allure-python-commons/src/allure_commons/_allure.py +++ b/allure-python-commons/src/allure_commons/_allure.py @@ -125,7 +125,7 @@ def tag(*tags): Dynamic.label(LabelType.TAG, *tags) @staticmethod - def id(id): # noqa: A003,A002 + def id(id): # noqa: A002 Dynamic.label(LabelType.ID, id) @staticmethod diff --git a/allure-python-commons/src/allure_commons/_core.py b/allure-python-commons/src/allure_commons/_core.py index 40d9deaf..8687891c 100644 --- a/allure-python-commons/src/allure_commons/_core.py +++ b/allure-python-commons/src/allure_commons/_core.py @@ -8,7 +8,7 @@ class MetaPluginManager(type): @staticmethod def get_plugin_manager(): if not MetaPluginManager._plugin_manager: - MetaPluginManager._plugin_manager = PluginManager('allure') + MetaPluginManager._plugin_manager = PluginManager("allure") MetaPluginManager._plugin_manager.add_hookspecs(_hooks.AllureUserHooks) MetaPluginManager._plugin_manager.add_hookspecs(_hooks.AllureDeveloperHooks) diff --git a/allure-python-commons/src/allure_commons/lifecycle.py b/allure-python-commons/src/allure_commons/lifecycle.py index 2e730e2e..f6a4ff33 100644 --- a/allure-python-commons/src/allure_commons/lifecycle.py +++ b/allure-python-commons/src/allure_commons/lifecycle.py @@ -125,7 +125,7 @@ def stop_after_fixture(self, uuid=None): def _attach(self, uuid, name=None, attachment_type=None, extension=None, parent_uuid=None): mime_type = attachment_type - extension = extension if extension else 'attach' + extension = extension if extension else "attach" if type(attachment_type) is AttachmentType: extension = attachment_type.extension diff --git a/allure-python-commons/src/allure_commons/logger.py b/allure-python-commons/src/allure_commons/logger.py index 55f956f2..da3df2da 100644 --- a/allure-python-commons/src/allure_commons/logger.py +++ b/allure-python-commons/src/allure_commons/logger.py @@ -22,7 +22,7 @@ def _report_item(self, item): indent = INDENT if os.environ.get("ALLURE_INDENT_OUTPUT") else None filename = item.file_pattern.format(prefix=uuid.uuid4()) data = asdict(item, filter=lambda _, v: v or v is False) - with io.open(self._report_dir / filename, 'w', encoding='utf8') as json_file: + with io.open(self._report_dir / filename, "w", encoding="utf8") as json_file: json.dump(data, json_file, indent=indent, ensure_ascii=False) @hookimpl @@ -41,9 +41,9 @@ def report_attached_file(self, source, file_name): @hookimpl def report_attached_data(self, body, file_name): destination = self._report_dir / file_name - with open(destination, 'wb') as attached_file: + with open(destination, "wb") as attached_file: if isinstance(body, str): - attached_file.write(body.encode('utf-8')) + attached_file.write(body.encode("utf-8")) else: attached_file.write(body) diff --git a/allure-python-commons/src/allure_commons/mapping.py b/allure-python-commons/src/allure_commons/mapping.py index 737d3390..0cd099f0 100644 --- a/allure-python-commons/src/allure_commons/mapping.py +++ b/allure-python-commons/src/allure_commons/mapping.py @@ -20,7 +20,7 @@ def allure_tag_sep(tag): def __is(kind, t): - return kind in [v for k, v in t.__dict__.items() if not k.startswith('__')] + return kind in [v for k, v in t.__dict__.items() if not k.startswith("__")] def parse_tag(tag, issue_pattern=None, link_pattern=None): @@ -51,7 +51,7 @@ def parse_tag(tag, issue_pattern=None, link_pattern=None): """ sep = allure_tag_sep(tag) schema, value = islice(chain(tag.split(sep, 1), [None]), 2) - prefix, kind, name = islice(chain(schema.split('.'), [None], [None]), 3) + prefix, kind, name = islice(chain(schema.split("."), [None], [None]), 3) if tag in [severity for severity in Severity]: return Label(name=LabelType.SEVERITY, value=tag) diff --git a/allure-python-commons/src/allure_commons/model2.py b/allure-python-commons/src/allure_commons/model2.py index d8591598..a117948c 100644 --- a/allure-python-commons/src/allure_commons/model2.py +++ b/allure-python-commons/src/allure_commons/model2.py @@ -4,7 +4,7 @@ TEST_GROUP_PATTERN = "{prefix}-container.json" TEST_CASE_PATTERN = "{prefix}-result.json" -ATTACHMENT_PATTERN = '{prefix}-attachment.{ext}' +ATTACHMENT_PATTERN = "{prefix}-attachment.{ext}" INDENT = 4 @@ -54,7 +54,7 @@ class TestResult(ExecutableItem): @attrs class TestStepResult(ExecutableItem): - id = attrib(default=None) # noqa: A003 + id = attrib(default=None) @attrs @@ -83,7 +83,7 @@ class Label: @attrs class Link: - type = attrib(default=None) # noqa: A003 + type = attrib(default=None) url = attrib(default=None) name = attrib(default=None) @@ -95,17 +95,16 @@ class StatusDetails: message = attrib(default=None) trace = attrib(default=None) - @attrs class Attachment: name = attrib(default=None) source = attrib(default=None) - type = attrib(default=None) # noqa: A003 + type = attrib(default=None) class Status: - FAILED = 'failed' - BROKEN = 'broken' - PASSED = 'passed' - SKIPPED = 'skipped' - UNKNOWN = 'unknown' + FAILED = "failed" + BROKEN = "broken" + PASSED = "passed" + SKIPPED = "skipped" + UNKNOWN = "unknown" diff --git a/allure-python-commons/src/allure_commons/reporter.py b/allure-python-commons/src/allure_commons/reporter.py index 2e1f4a89..14bbeb17 100644 --- a/allure-python-commons/src/allure_commons/reporter.py +++ b/allure-python-commons/src/allure_commons/reporter.py @@ -141,7 +141,7 @@ def stop_step(self, uuid, **kwargs): def _attach(self, uuid, name=None, attachment_type=None, extension=None, parent_uuid=None): mime_type = attachment_type - extension = extension if extension else 'attach' + extension = extension if extension else "attach" if type(attachment_type) is AttachmentType: extension = attachment_type.extension diff --git a/allure-python-commons/src/allure_commons/types.py b/allure-python-commons/src/allure_commons/types.py index e631e427..70f676cd 100644 --- a/allure-python-commons/src/allure_commons/types.py +++ b/allure-python-commons/src/allure_commons/types.py @@ -1,37 +1,37 @@ from enum import Enum -ALLURE_UNIQUE_LABELS = ['severity', 'thread', 'host'] +ALLURE_UNIQUE_LABELS = ["severity", "thread", "host"] class Severity(str, Enum): - BLOCKER = 'blocker' - CRITICAL = 'critical' - NORMAL = 'normal' - MINOR = 'minor' - TRIVIAL = 'trivial' + BLOCKER = "blocker" + CRITICAL = "critical" + NORMAL = "normal" + MINOR = "minor" + TRIVIAL = "trivial" class LinkType: - LINK = 'link' - ISSUE = 'issue' - TEST_CASE = 'tms' + LINK = "link" + ISSUE = "issue" + TEST_CASE = "tms" class LabelType(str): - EPIC = 'epic' - FEATURE = 'feature' - STORY = 'story' - PARENT_SUITE = 'parentSuite' - SUITE = 'suite' - SUB_SUITE = 'subSuite' - SEVERITY = 'severity' - THREAD = 'thread' - HOST = 'host' - TAG = 'tag' - ID = 'as_id' - FRAMEWORK = 'framework' - LANGUAGE = 'language' - MANUAL = 'ALLURE_MANUAL' + EPIC = "epic" + FEATURE = "feature" + STORY = "story" + PARENT_SUITE = "parentSuite" + SUITE = "suite" + SUB_SUITE = "subSuite" + SEVERITY = "severity" + THREAD = "thread" + HOST = "host" + TAG = "tag" + ID = "as_id" + FRAMEWORK = "framework" + LANGUAGE = "language" + MANUAL = "ALLURE_MANUAL" class AttachmentType(Enum): @@ -66,6 +66,6 @@ def __init__(self, mime_type, extension): class ParameterMode(Enum): - HIDDEN = 'hidden' - MASKED = 'masked' + HIDDEN = "hidden" + MASKED = "masked" DEFAULT = None diff --git a/allure-python-commons/src/allure_commons/utils.py b/allure-python-commons/src/allure_commons/utils.py index 5ba0d377..c50cb7ec 100644 --- a/allure-python-commons/src/allure_commons/utils.py +++ b/allure-python-commons/src/allure_commons/utils.py @@ -21,7 +21,7 @@ def md5(*args): if not isinstance(arg, bytes): if not isinstance(arg, str): arg = repr(arg) - arg = arg.encode('utf-8') + arg = arg.encode("utf-8") m.update(arg) return m.hexdigest() @@ -37,11 +37,11 @@ def now(): def platform_label(): major_version, *_ = platform.python_version_tuple() implementation = platform.python_implementation().lower() - return f'{implementation}{major_version}' + return f"{implementation}{major_version}" def thread_tag(): - return '{0}-{1}'.format(os.getpid(), threading.current_thread().name) + return "{0}-{1}".format(os.getpid(), threading.current_thread().name) def host_tag(): @@ -241,7 +241,7 @@ def func_parameters(func, *args, **kwargs): varargs = args[len(arg_spec.args):] parameters.update({arg_spec.varargs: varargs} if varargs else {}) - if arg_spec.args and arg_spec.args[0] in ['cls', 'self']: + if arg_spec.args and arg_spec.args[0] in ["cls", "self"]: args_dict.pop(arg_spec.args[0], None) if kwargs: @@ -269,7 +269,7 @@ def func_parameters(func, *args, **kwargs): def format_traceback(exc_traceback): - return ''.join(traceback.format_tb(exc_traceback)) if exc_traceback else None + return "".join(traceback.format_tb(exc_traceback)) if exc_traceback else None def format_exception(etype, value): @@ -320,7 +320,7 @@ def format_exception(etype, value): ... format_exception(etype, e) # doctest: +ELLIPSIS "AssertionError: \\nExpected:...but:..." """ - return '\n'.join(format_exception_only(etype, value)) if etype or value else None + return "\n".join(format_exception_only(etype, value)) if etype or value else None def get_testplan(): @@ -328,7 +328,7 @@ def get_testplan(): file_path = os.environ.get("ALLURE_TESTPLAN_PATH") if file_path and os.path.exists(file_path): - with open(file_path, 'r') as plan_file: + with open(file_path, "r") as plan_file: plan = json.load(plan_file) planned_tests = plan.get("tests", []) diff --git a/allure-robotframework/pyproject.toml b/allure-robotframework/pyproject.toml index 0ee96703..2d6844e1 100644 --- a/allure-robotframework/pyproject.toml +++ b/allure-robotframework/pyproject.toml @@ -1,5 +1,5 @@ [tool.poe.tasks] -linter = "flake8 ./src" +linter = "ruff check" [tool.poe.tasks.tests] shell = "python -m doctest ./src/listener/utils.py && pytest ../tests/allure_robotframework" diff --git a/allure-robotframework/setup.py b/allure-robotframework/setup.py index 8b194c29..ca07e98f 100644 --- a/allure-robotframework/setup.py +++ b/allure-robotframework/setup.py @@ -4,21 +4,21 @@ PACKAGE = "allure-robotframework" classifiers = [ - 'Development Status :: 5 - Production/Stable', - 'Framework :: Robot Framework', - 'Framework :: Robot Framework :: Tool', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Topic :: Software Development :: Quality Assurance', - 'Topic :: Software Development :: Testing', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', + "Development Status :: 5 - Production/Stable", + "Framework :: Robot Framework", + "Framework :: Robot Framework :: Tool", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Topic :: Software Development :: Quality Assurance", + "Topic :: Software Development :: Testing", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] setup_requires = [ @@ -41,7 +41,7 @@ def get_readme(fname): return open(os.path.join(os.path.dirname(__file__), fname)).read() -if __name__ == '__main__': +if __name__ == "__main__": setup( name=PACKAGE, use_scm_version=prepare_version, @@ -50,9 +50,9 @@ def get_readme(fname): install_requires=install_requires, setup_requires=setup_requires, keywords="allure reporting robotframework", - packages=['allure_robotframework', 'AllureLibrary'], - package_dir={"allure_robotframework": "src/listener", 'AllureLibrary': 'src/library'}, - py_modules=['allure_robotframework'], + packages=["allure_robotframework", "AllureLibrary"], + package_dir={"allure_robotframework": "src/listener", "AllureLibrary": "src/library"}, + py_modules=["allure_robotframework"], url="https://allurereport.org/", project_urls={ "Source": "https://github.com/allure-framework/allure-python", diff --git a/allure-robotframework/src/library/__init__.py b/allure-robotframework/src/library/__init__.py index 0786652e..ba680b46 100644 --- a/allure-robotframework/src/library/__init__.py +++ b/allure-robotframework/src/library/__init__.py @@ -1,3 +1,3 @@ from .allure_library import attach, attach_file -__all__ = ['attach', 'attach_file'] +__all__ = ["attach", "attach_file"] diff --git a/allure-robotframework/src/library/allure_library.py b/allure-robotframework/src/library/allure_library.py index a7dc93e5..2b77f5e7 100644 --- a/allure-robotframework/src/library/allure_library.py +++ b/allure-robotframework/src/library/allure_library.py @@ -1,7 +1,7 @@ import allure -__all__ = ['attach', 'attach_file'] +__all__ = ["attach", "attach_file"] def _attachment_type(name): diff --git a/allure-robotframework/src/listener/__init__.py b/allure-robotframework/src/listener/__init__.py index d2640a4e..92740385 100644 --- a/allure-robotframework/src/listener/__init__.py +++ b/allure-robotframework/src/listener/__init__.py @@ -1,4 +1,4 @@ from allure_robotframework.robot_listener import allure_robotframework from allure_robotframework.allure_testplan import allure_testplan as testplan -__all__ = ['allure_robotframework', "testplan"] +__all__ = ["allure_robotframework", "testplan"] diff --git a/allure-robotframework/src/listener/allure_listener.py b/allure-robotframework/src/listener/allure_listener.py index 29b4e0e3..045c491a 100644 --- a/allure-robotframework/src/listener/allure_listener.py +++ b/allure-robotframework/src/listener/allure_listener.py @@ -39,8 +39,8 @@ def get_status_details(exc_type, exception, exc_traceback): def pool_id(): - pabot_pool_id = BuiltIn().get_variable_value('${PABOTEXECUTIONPOOLID}') - pabot_caller_id = BuiltIn().get_variable_value('${CALLER_ID}') + pabot_pool_id = BuiltIn().get_variable_value("${PABOTEXECUTIONPOOLID}") + pabot_caller_id = BuiltIn().get_variable_value("${CALLER_ID}") return f"{pabot_pool_id}-{pabot_caller_id}" if all([ pabot_pool_id, pabot_caller_id @@ -52,9 +52,9 @@ def get_message_time(timestamp): return int(s_time.timestamp() * 1000) -LOG_MESSAGE_FORMAT = '
[{level}] {message}
' +LOG_MESSAGE_FORMAT = "[{level}] {message}
" FAIL_MESSAGE_FORMAT = '[{level}] {message}
' -MAX_STEP_MESSAGE_COUNT = int(os.getenv('ALLURE_MAX_STEP_MESSAGE_COUNT', 0)) +MAX_STEP_MESSAGE_COUNT = int(os.getenv("ALLURE_MAX_STEP_MESSAGE_COUNT", 0)) class AllureListener: @@ -70,8 +70,8 @@ def start_suite_container(self, name, attributes): pass def stop_suite_container(self, name, attributes): - suite_status = get_allure_status(attributes.get('status')) - suite_message = attributes.get('message') + suite_status = get_allure_status(attributes.get("status")) + suite_message = attributes.get("message") with self.lifecycle.update_container() as container: for uuid in container.children: @@ -89,8 +89,8 @@ def start_test_container(self, name, attributes): pass def stop_test_container(self, name, attributes): - suite_status = get_allure_status(attributes.get('status')) - suite_message = attributes.get('message') + suite_status = get_allure_status(attributes.get("status")) + suite_message = attributes.get("message") with self.lifecycle.schedule_test_case() as test_result: if test_result.status == Status.PASSED and suite_message: @@ -106,7 +106,7 @@ def start_before_fixture(self, name): fixture.name = name def stop_before_fixture(self, attributes, messages): - status = attributes.get('status') + status = attributes.get("status") self._report_messages(status, messages) with self.lifecycle.update_before_fixture() as fixture: fixture.status = get_allure_status(status) @@ -118,7 +118,7 @@ def start_after_fixture(self, name): fixture.name = name def stop_after_fixture(self, attributes, messages): - status = attributes.get('status') + status = attributes.get("status") self._report_messages(status, messages) with self.lifecycle.update_after_fixture() as fixture: fixture.status = get_allure_status(status) @@ -128,7 +128,7 @@ def stop_after_fixture(self, attributes, messages): def start_test(self, name, attributes): uuid = uuid4() with self.lifecycle.schedule_test_case(uuid=uuid) as test_result: - long_name = attributes.get('longname') + long_name = attributes.get("longname") test_result.name = name test_result.fullName = long_name test_result.titlePath = attributes.get("titlepath", []) @@ -140,26 +140,26 @@ def start_test(self, name, attributes): container.children.append(uuid) def stop_test(self, _, attributes, messages): - self._report_messages(attributes.get('status'), messages) + self._report_messages(attributes.get("status"), messages) - if 'skipped' in [tag.lower() for tag in attributes['tags']]: - attributes['status'] = RobotStatus.SKIPPED + if "skipped" in [tag.lower() for tag in attributes["tags"]]: + attributes["status"] = RobotStatus.SKIPPED with self.lifecycle.update_test_case() as test_result: test_result.stop = now() - test_result.description = attributes.get('doc') - test_result.status = get_allure_status(attributes.get('status')) - test_result.labels.extend(get_allure_suites(attributes.get('longname'))) - test_result.labels.append(Label(name=LabelType.FRAMEWORK, value='robotframework')) + test_result.description = attributes.get("doc") + test_result.status = get_allure_status(attributes.get("status")) + test_result.labels.extend(get_allure_suites(attributes.get("longname"))) + test_result.labels.append(Label(name=LabelType.FRAMEWORK, value="robotframework")) test_result.labels.append(Label(name=LabelType.LANGUAGE, value=self._platform)) test_result.labels.append(Label(name=LabelType.HOST, value=self._host)) test_result.labels.append(Label(name=LabelType.THREAD, value=pool_id())) - tags = attributes.get('tags', ()) + tags = attributes.get("tags", ()) test_result.labels.extend(allure_labels(tags)) - test_result.statusDetails = StatusDetails(message=attributes.get('message'), + test_result.statusDetails = StatusDetails(message=attributes.get("message"), trace=self._current_tb) - if attributes.get('critical') == 'yes': + if attributes.get("critical") == "yes": test_result.labels.append(Label(name=LabelType.SEVERITY, value=Severity.CRITICAL)) for link_type in (LinkType.ISSUE, LinkType.TEST_CASE, LinkType.LINK): @@ -172,11 +172,11 @@ def start_keyword(self, name): step.name = name def stop_keyword(self, attributes, messages): - status = attributes.get('status') + status = attributes.get("status") self._report_messages(status, messages) with self.lifecycle.update_step() as step: step.status = get_allure_status(status) - step.parameters = get_allure_parameters(attributes.get('args')) + step.parameters = get_allure_parameters(attributes.get("args")) step.statusDetails = StatusDetails(message=self._current_msg, trace=self._current_tb) self.lifecycle.stop_step() @@ -188,8 +188,8 @@ def _report_messages(self, status, messages): self._current_tb, self._current_msg = None, None for message, next_message in zip_longest(messages, messages[1:]): - name = message.get('message') - level = message.get('level') + name = message.get("message") + level = message.get("level") message_format = FAIL_MESSAGE_FORMAT if level in RobotLogLevel.CRITICAL_LEVELS else LOG_MESSAGE_FORMAT if level == RobotLogLevel.FAIL: @@ -197,7 +197,7 @@ def _report_messages(self, status, messages): self._current_tb = next_message.get("message") if has_trace and next_message else self._current_tb if len(messages) > MAX_STEP_MESSAGE_COUNT: - attachment += message_format.format(level=level, message=name.replace('\n', '