klab-pytest-toolkit-decorators 0.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- klab_pytest_toolkit_decorators-0.0.0/.gitignore +177 -0
- klab_pytest_toolkit_decorators-0.0.0/PKG-INFO +51 -0
- klab_pytest_toolkit_decorators-0.0.0/README.md +37 -0
- klab_pytest_toolkit_decorators-0.0.0/pyproject.toml +39 -0
- klab_pytest_toolkit_decorators-0.0.0/src/klab_pytest_toolkit_decorators/__init__.py +4 -0
- klab_pytest_toolkit_decorators-0.0.0/src/klab_pytest_toolkit_decorators/compliance.py +39 -0
- klab_pytest_toolkit_decorators-0.0.0/src/klab_pytest_toolkit_decorators/plugin.py +30 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Created by https://www.toptal.com/developers/gitignore/api/python
|
|
2
|
+
# Edit at https://www.toptal.com/developers/gitignore?templates=python
|
|
3
|
+
|
|
4
|
+
### Custom ###
|
|
5
|
+
pytest.xml
|
|
6
|
+
pytest-coverage.txt
|
|
7
|
+
|
|
8
|
+
### Python ###
|
|
9
|
+
# Byte-compiled / optimized / DLL files
|
|
10
|
+
__pycache__/
|
|
11
|
+
*.py[cod]
|
|
12
|
+
*$py.class
|
|
13
|
+
|
|
14
|
+
# Distribution / packaging
|
|
15
|
+
.Python
|
|
16
|
+
build/
|
|
17
|
+
develop-eggs/
|
|
18
|
+
dist/
|
|
19
|
+
downloads/
|
|
20
|
+
eggs/
|
|
21
|
+
.eggs/
|
|
22
|
+
lib/
|
|
23
|
+
lib64/
|
|
24
|
+
parts/
|
|
25
|
+
sdist/
|
|
26
|
+
var/
|
|
27
|
+
wheels/
|
|
28
|
+
share/python-wheels/
|
|
29
|
+
*.egg-info/
|
|
30
|
+
.installed.cfg
|
|
31
|
+
*.egg
|
|
32
|
+
MANIFEST
|
|
33
|
+
|
|
34
|
+
# PyInstaller
|
|
35
|
+
# Usually these files are written by a python script from a template
|
|
36
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
37
|
+
*.manifest
|
|
38
|
+
*.spec
|
|
39
|
+
|
|
40
|
+
# Installer logs
|
|
41
|
+
pip-log.txt
|
|
42
|
+
pip-delete-this-directory.txt
|
|
43
|
+
|
|
44
|
+
# Unit test / coverage reports
|
|
45
|
+
htmlcov/
|
|
46
|
+
.tox/
|
|
47
|
+
.nox/
|
|
48
|
+
.coverage
|
|
49
|
+
.coverage.*
|
|
50
|
+
.cache
|
|
51
|
+
nosetests.xml
|
|
52
|
+
coverage.xml
|
|
53
|
+
*.cover
|
|
54
|
+
*.py,cover
|
|
55
|
+
.hypothesis/
|
|
56
|
+
.pytest_cache/
|
|
57
|
+
cover/
|
|
58
|
+
|
|
59
|
+
# Translations
|
|
60
|
+
*.mo
|
|
61
|
+
*.pot
|
|
62
|
+
|
|
63
|
+
# Django stuff:
|
|
64
|
+
*.log
|
|
65
|
+
local_settings.py
|
|
66
|
+
db.sqlite3
|
|
67
|
+
db.sqlite3-journal
|
|
68
|
+
|
|
69
|
+
# Flask stuff:
|
|
70
|
+
instance/
|
|
71
|
+
.webassets-cache
|
|
72
|
+
|
|
73
|
+
# Scrapy stuff:
|
|
74
|
+
.scrapy
|
|
75
|
+
|
|
76
|
+
# Sphinx documentation
|
|
77
|
+
docs/_build/
|
|
78
|
+
|
|
79
|
+
# PyBuilder
|
|
80
|
+
.pybuilder/
|
|
81
|
+
target/
|
|
82
|
+
|
|
83
|
+
# Jupyter Notebook
|
|
84
|
+
.ipynb_checkpoints
|
|
85
|
+
|
|
86
|
+
# IPython
|
|
87
|
+
profile_default/
|
|
88
|
+
ipython_config.py
|
|
89
|
+
|
|
90
|
+
# pyenv
|
|
91
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
92
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
93
|
+
# .python-version
|
|
94
|
+
|
|
95
|
+
# pipenv
|
|
96
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
97
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
98
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
99
|
+
# install all needed dependencies.
|
|
100
|
+
#Pipfile.lock
|
|
101
|
+
|
|
102
|
+
# poetry
|
|
103
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
104
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
105
|
+
# commonly ignored for libraries.
|
|
106
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
107
|
+
#poetry.lock
|
|
108
|
+
|
|
109
|
+
# pdm
|
|
110
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
111
|
+
#pdm.lock
|
|
112
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
113
|
+
# in version control.
|
|
114
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
115
|
+
.pdm.toml
|
|
116
|
+
|
|
117
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
118
|
+
__pypackages__/
|
|
119
|
+
|
|
120
|
+
# Celery stuff
|
|
121
|
+
celerybeat-schedule
|
|
122
|
+
celerybeat.pid
|
|
123
|
+
|
|
124
|
+
# SageMath parsed files
|
|
125
|
+
*.sage.py
|
|
126
|
+
|
|
127
|
+
# Environments
|
|
128
|
+
.env
|
|
129
|
+
.venv
|
|
130
|
+
env/
|
|
131
|
+
venv/
|
|
132
|
+
ENV/
|
|
133
|
+
env.bak/
|
|
134
|
+
venv.bak/
|
|
135
|
+
|
|
136
|
+
# Spyder project settings
|
|
137
|
+
.spyderproject
|
|
138
|
+
.spyproject
|
|
139
|
+
|
|
140
|
+
# Rope project settings
|
|
141
|
+
.ropeproject
|
|
142
|
+
|
|
143
|
+
# mkdocs documentation
|
|
144
|
+
/site
|
|
145
|
+
|
|
146
|
+
# mypy
|
|
147
|
+
.mypy_cache/
|
|
148
|
+
.dmypy.json
|
|
149
|
+
dmypy.json
|
|
150
|
+
|
|
151
|
+
# Pyre type checker
|
|
152
|
+
.pyre/
|
|
153
|
+
|
|
154
|
+
# pytype static type analyzer
|
|
155
|
+
.pytype/
|
|
156
|
+
|
|
157
|
+
# Cython debug symbols
|
|
158
|
+
cython_debug/
|
|
159
|
+
|
|
160
|
+
# PyCharm
|
|
161
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
162
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
163
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
164
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
165
|
+
#.idea/
|
|
166
|
+
|
|
167
|
+
### Python Patch ###
|
|
168
|
+
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
|
|
169
|
+
poetry.toml
|
|
170
|
+
|
|
171
|
+
# ruff
|
|
172
|
+
.ruff_cache/
|
|
173
|
+
|
|
174
|
+
# LSP config files
|
|
175
|
+
pyrightconfig.json
|
|
176
|
+
|
|
177
|
+
# End of https://www.toptal.com/developers/gitignore/api/python
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: klab-pytest-toolkit-decorators
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Pytest decorators for the Klab Pytest Toolkit
|
|
5
|
+
Author-email: Burak Kizilkaya <burak.kizilkaya@outlook.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Requires-Python: <4,>=3.11
|
|
12
|
+
Requires-Dist: pytest>=8.3.5
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# Klab Pytest Toolkit - Decorators
|
|
16
|
+
|
|
17
|
+
Custom pytest decorators for marking and annotating tests.
|
|
18
|
+
|
|
19
|
+
At the moment the package provides the following decorator:
|
|
20
|
+
|
|
21
|
+
- `@requirement(id: str)`: Marks a test with a requirement ID for traceability. The ID is added to the junit xml output.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install klab_pytest_toolkit_decorators
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Requirement Decorator
|
|
32
|
+
|
|
33
|
+
Mark tests with requirement IDs for traceability:
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from klab_pytest_toolkit_decorators import requirement
|
|
37
|
+
|
|
38
|
+
@requirement("REQ-001")
|
|
39
|
+
def test_something():
|
|
40
|
+
assert True
|
|
41
|
+
|
|
42
|
+
@requirement("REQ-002")
|
|
43
|
+
async def test_async_something():
|
|
44
|
+
assert True
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The decorator works with both synchronous and asynchronous test functions. The requirement IDs are added to the junit xml output.
|
|
48
|
+
|
|
49
|
+
## License
|
|
50
|
+
|
|
51
|
+
MIT
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Klab Pytest Toolkit - Decorators
|
|
2
|
+
|
|
3
|
+
Custom pytest decorators for marking and annotating tests.
|
|
4
|
+
|
|
5
|
+
At the moment the package provides the following decorator:
|
|
6
|
+
|
|
7
|
+
- `@requirement(id: str)`: Marks a test with a requirement ID for traceability. The ID is added to the junit xml output.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install klab_pytest_toolkit_decorators
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Requirement Decorator
|
|
18
|
+
|
|
19
|
+
Mark tests with requirement IDs for traceability:
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from klab_pytest_toolkit_decorators import requirement
|
|
23
|
+
|
|
24
|
+
@requirement("REQ-001")
|
|
25
|
+
def test_something():
|
|
26
|
+
assert True
|
|
27
|
+
|
|
28
|
+
@requirement("REQ-002")
|
|
29
|
+
async def test_async_something():
|
|
30
|
+
assert True
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The decorator works with both synchronous and asynchronous test functions. The requirement IDs are added to the junit xml output.
|
|
34
|
+
|
|
35
|
+
## License
|
|
36
|
+
|
|
37
|
+
MIT
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "klab-pytest-toolkit-decorators"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Pytest decorators for the Klab Pytest Toolkit"
|
|
9
|
+
authors = [{ name = "Burak Kizilkaya", email = "burak.kizilkaya@outlook.com" }]
|
|
10
|
+
requires-python = ">=3.11,<4"
|
|
11
|
+
readme = "README.md"
|
|
12
|
+
license = "MIT"
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"pytest>=8.3.5",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.entry-points.pytest11]
|
|
24
|
+
klab_pytest_toolkit_decorators = "klab_pytest_toolkit_decorators.plugin"
|
|
25
|
+
|
|
26
|
+
[tool.hatch.version]
|
|
27
|
+
path = "src/klab_pytest_toolkit_decorators/__init__.py"
|
|
28
|
+
|
|
29
|
+
[tool.hatch.build.targets.sdist]
|
|
30
|
+
exclude = [
|
|
31
|
+
"tests",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[tool.pytest.ini_options]
|
|
35
|
+
asyncio_mode = "auto"
|
|
36
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
37
|
+
pythonpath = [
|
|
38
|
+
"."
|
|
39
|
+
]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
import inspect
|
|
3
|
+
from collections.abc import Awaitable, Callable
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def requirement(*req_ids):
|
|
9
|
+
"""Custom decorator to mark a test with requirement ID(s) and log them in the JUnit report.
|
|
10
|
+
|
|
11
|
+
Supports multiple requirements in several ways:
|
|
12
|
+
- Single requirement: @requirement("REQ-001")
|
|
13
|
+
- Multiple arguments: @requirement("REQ-001", "REQ-002", "REQ-003")
|
|
14
|
+
- Multiple decorators: @requirement("REQ-001") @requirement("REQ-002")
|
|
15
|
+
"""
|
|
16
|
+
if not req_ids:
|
|
17
|
+
raise ValueError("At least one requirement ID must be provided")
|
|
18
|
+
|
|
19
|
+
def decorator(func: Callable) -> Callable[[], Awaitable[None]]:
|
|
20
|
+
# Apply markers for each requirement ID at decoration time
|
|
21
|
+
marked_func = func
|
|
22
|
+
for req_id in req_ids:
|
|
23
|
+
marked_func = pytest.mark.requirement(req_id)(marked_func)
|
|
24
|
+
|
|
25
|
+
@functools.wraps(marked_func)
|
|
26
|
+
async def async_wrapper(*args, **kwargs):
|
|
27
|
+
return await marked_func(*args, **kwargs)
|
|
28
|
+
|
|
29
|
+
@functools.wraps(marked_func)
|
|
30
|
+
def sync_wrapper(*args, **kwargs):
|
|
31
|
+
return marked_func(*args, **kwargs)
|
|
32
|
+
|
|
33
|
+
wrapper = async_wrapper if inspect.iscoroutinefunction(func) else sync_wrapper
|
|
34
|
+
# Copy over the pytest markers to the wrapper
|
|
35
|
+
# type: ignore is needed because pytestmark is dynamically added
|
|
36
|
+
setattr(wrapper, "pytestmark", getattr(marked_func, "pytestmark", []))
|
|
37
|
+
return wrapper
|
|
38
|
+
|
|
39
|
+
return decorator
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Pytest plugin to register custom markers."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def pytest_configure(config):
|
|
5
|
+
"""Register custom markers for klab-pytest-toolkit-decorators."""
|
|
6
|
+
config.addinivalue_line(
|
|
7
|
+
"markers", "requirement(req_id): mark test with a requirement ID for traceability"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def pytest_collection_modifyitems(items):
|
|
12
|
+
"""Add requirement IDs to test properties for JUnit XML report."""
|
|
13
|
+
for item in items:
|
|
14
|
+
# Get all requirement markers (there can be multiple)
|
|
15
|
+
requirement_markers = [m for m in item.iter_markers(name="requirement")]
|
|
16
|
+
if requirement_markers:
|
|
17
|
+
# Collect all requirement IDs
|
|
18
|
+
req_ids = []
|
|
19
|
+
for marker in requirement_markers:
|
|
20
|
+
if marker.args:
|
|
21
|
+
req_ids.append(str(marker.args[0]))
|
|
22
|
+
|
|
23
|
+
# Add all requirements as properties for JUnit XML
|
|
24
|
+
# Can be added as comma-separated single property or individual properties
|
|
25
|
+
if req_ids:
|
|
26
|
+
# Add as comma-separated list
|
|
27
|
+
item.user_properties.append(("requirements", ", ".join(req_ids)))
|
|
28
|
+
# Also add individual properties for each requirement
|
|
29
|
+
for req_id in req_ids:
|
|
30
|
+
item.user_properties.append(("requirement", req_id))
|