qapytest 0.1.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.
Files changed (45) hide show
  1. qapytest-0.1.0/.gitignore +33 -0
  2. qapytest-0.1.0/.pre-commit-config.yaml +6 -0
  3. qapytest-0.1.0/CHANGELOG.md +34 -0
  4. qapytest-0.1.0/LICENSE +21 -0
  5. qapytest-0.1.0/PKG-INFO +233 -0
  6. qapytest-0.1.0/README.md +180 -0
  7. qapytest-0.1.0/demo.py +203 -0
  8. qapytest-0.1.0/docs/API.md +226 -0
  9. qapytest-0.1.0/docs/CLI.md +87 -0
  10. qapytest-0.1.0/licenses/httpx.LICENSE +12 -0
  11. qapytest-0.1.0/licenses/jinja2.LICENSE +28 -0
  12. qapytest-0.1.0/licenses/jsonschema.LICENSE +19 -0
  13. qapytest-0.1.0/licenses/pytest.LICENSE +21 -0
  14. qapytest-0.1.0/licenses/python_dotenv.LICENSE +27 -0
  15. qapytest-0.1.0/licenses/redis-py.LICENSE +21 -0
  16. qapytest-0.1.0/licenses/sqlalchemy.LICENSE +19 -0
  17. qapytest-0.1.0/pyproject.toml +83 -0
  18. qapytest-0.1.0/qapytest/__init__.py +21 -0
  19. qapytest-0.1.0/qapytest/_assets/_log_tree.html.jinja2 +51 -0
  20. qapytest-0.1.0/qapytest/_assets/report.html.jinja2 +141 -0
  21. qapytest-0.1.0/qapytest/_assets/scripts.js +442 -0
  22. qapytest-0.1.0/qapytest/_assets/styles.css +649 -0
  23. qapytest-0.1.0/qapytest/_attach.py +139 -0
  24. qapytest-0.1.0/qapytest/_config.py +35 -0
  25. qapytest-0.1.0/qapytest/_graphql.py +112 -0
  26. qapytest-0.1.0/qapytest/_http.py +87 -0
  27. qapytest-0.1.0/qapytest/_internal.py +277 -0
  28. qapytest-0.1.0/qapytest/_json_validation.py +138 -0
  29. qapytest-0.1.0/qapytest/_plugin.py +163 -0
  30. qapytest-0.1.0/qapytest/_redis.py +178 -0
  31. qapytest-0.1.0/qapytest/_report.py +159 -0
  32. qapytest-0.1.0/qapytest/_soft_assert.py +68 -0
  33. qapytest-0.1.0/qapytest/_sql.py +152 -0
  34. qapytest-0.1.0/qapytest/_step.py +64 -0
  35. qapytest-0.1.0/tests/test_attach.py +188 -0
  36. qapytest-0.1.0/tests/test_graphql_client.py +208 -0
  37. qapytest-0.1.0/tests/test_http_client.py +165 -0
  38. qapytest-0.1.0/tests/test_integration.py +83 -0
  39. qapytest-0.1.0/tests/test_internal_functions.py +357 -0
  40. qapytest-0.1.0/tests/test_markers.py +437 -0
  41. qapytest-0.1.0/tests/test_redis_client.py +276 -0
  42. qapytest-0.1.0/tests/test_soft_assert.py +91 -0
  43. qapytest-0.1.0/tests/test_sql_client.py +127 -0
  44. qapytest-0.1.0/tests/test_step.py +70 -0
  45. qapytest-0.1.0/uv.lock +742 -0
@@ -0,0 +1,33 @@
1
+ # MacOS
2
+ .DS_Store
3
+
4
+ # Windows
5
+ Thumbs.db
6
+ ehthumbs.db
7
+ Desktop.ini
8
+ $RECYCLE.BIN/
9
+
10
+ # Python-generated files
11
+ __pycache__/
12
+ *.py[oc]
13
+ build/
14
+ dist/
15
+ wheels/
16
+ *.egg-info
17
+
18
+ # IDE specific files
19
+ .vscode/
20
+ .idea/
21
+
22
+ # Virtual environments
23
+ venv/
24
+ .venv/
25
+ **/*.env
26
+
27
+ # Data
28
+ **/*.html
29
+ **/*.log
30
+
31
+ # PyTest
32
+ **/*cache*
33
+ **/*.pyc
@@ -0,0 +1,6 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.12.12
4
+ hooks:
5
+ - id: ruff
6
+ - id: ruff-format
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2025-09-19
9
+
10
+ ### Added
11
+ - 🚀 **Initial release** of QaPyTest - powerful testing framework for QA engineers
12
+ - 📊 **HTML report generation** with customizable themes (light/dark/auto)
13
+ - 🎯 **Soft assertions** - collect multiple failures in single test run
14
+ - 📝 **Structured test steps** with nested hierarchy support
15
+ - 📎 **Attachments system** - add files, logs, and screenshots to reports
16
+ - 🌐 **HttpClient** - built-in HTTP client with automatic request/response logging
17
+ - 🗄️ **SqlClient** - direct database access for SQL queries and validation
18
+ - 🔴 **RedisClient** - Redis integration with automatic JSON serialization
19
+ - 📊 **GraphQLClient** - GraphQL query execution with error handling
20
+ - ✅ **JSON Schema validation** - validate API responses with soft-assert support
21
+ - 🏷️ **Custom pytest markers** - `@pytest.mark.title()` and `@pytest.mark.component()`
22
+ - ⚙️ **CLI options** - environment file loading, report customization, theme selection
23
+ - 🔧 **Environment configuration** - `.env` file support with override options
24
+ - 📚 **Comprehensive documentation** - API reference and CLI guide
25
+
26
+ ### Features
27
+ - Python 3.10+ support
28
+ - Pytest plugin architecture
29
+ - Self-contained HTML reports
30
+ - Automatic request/response timing
31
+ - Configurable attachment size limits
32
+ - Professional report styling with responsive design
33
+
34
+ [0.1.0]: https://github.com/o73k51i/qapytest/releases/tag/v0.1.0
qapytest-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 o73k51i
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.4
2
+ Name: qapytest
3
+ Version: 0.1.0
4
+ Summary: A powerful testing framework based on pytest, specifically designed for QA engineers
5
+ Project-URL: Homepage, https://github.com/o73k51i/qapytest
6
+ Project-URL: Repository, https://github.com/o73k51i/qapytest
7
+ Project-URL: Documentation, https://github.com/o73k51i/qapytest/blob/main/README.md
8
+ Project-URL: Bug Reports, https://github.com/o73k51i/qapytest/issues
9
+ Author-email: o73k51i <o73k51i@proton.me>
10
+ License: MIT License
11
+
12
+ Copyright (c) 2025 o73k51i
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: automation,graphql,http,pytest,qa,redis,soft-assert,sql,test,testing
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Framework :: Pytest
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.10
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Programming Language :: Python :: 3.13
42
+ Classifier: Topic :: Software Development :: Quality Assurance
43
+ Classifier: Topic :: Software Development :: Testing
44
+ Requires-Python: <3.14,>=3.10
45
+ Requires-Dist: httpx>=0.28.1
46
+ Requires-Dist: jinja2>=3.1.6
47
+ Requires-Dist: jsonschema>=4.25.1
48
+ Requires-Dist: pytest>=8.4.2
49
+ Requires-Dist: python-dotenv>=1.1.1
50
+ Requires-Dist: redis>=6.4.0
51
+ Requires-Dist: sqlalchemy>=2.0.43
52
+ Description-Content-Type: text/markdown
53
+
54
+ # QaPyTest
55
+
56
+ [![PyPI version](https://img.shields.io/pypi/v/qapytest.svg)](https://pypi.org/project/qapytest/)
57
+ [![Python versions](https://img.shields.io/pypi/pyversions/qapytest.svg)](https://pypi.org/project/qapytest/)
58
+ [![License](https://img.shields.io/github/license/o73k51i/qapytest.svg)](https://github.com/o73k51i/qapytest/blob/main/LICENSE)
59
+ [![Downloads](https://img.shields.io/pypi/dm/qapytest.svg)](https://pypi.org/project/qapytest/)
60
+ [![GitHub stars](https://img.shields.io/github/stars/o73k51i/qapytest.svg?style=social)](https://github.com/o73k51i/qapytest)
61
+
62
+ `QaPyTest` — a powerful testing framework based on pytest, specifically designed for QA engineers.
63
+ Turn your ordinary tests into detailed, structured reports with built-in HTTP, SQL, Redis and GraphQL clients.
64
+
65
+ 🎯 **QA made for QA** — every feature is designed for real testing and debugging needs.
66
+
67
+ ## ⚡ Why QaPyTest?
68
+
69
+ - **🚀 Ready to use:** Install → run → get a beautiful report
70
+ - **🔧 Built-in clients:** HTTP, SQL, Redis, GraphQL — all in one package
71
+ - **📊 Professional reports:** HTML reports with attachments and logs
72
+ - **🎯 Soft assertions:** Collect multiple failures in one run instead of stopping at the first
73
+ - **📝 Structured steps:** Make your tests self-documenting
74
+ - **🔍 Debugging friendly:** Full traceability of every action in the test
75
+
76
+ ## ⚙️ Key features
77
+
78
+ - **HTML report generation:** simple report at `report.html`.
79
+ - **Soft assertions:** allow collecting multiple failures in a single run without immediately ending the test.
80
+ - **Advanced steps:** structured logging of test steps for better report readability.
81
+ - **Attachments:** ability to add files, logs and screenshots to test reports.
82
+ - **HTTP client:** client for performing HTTP requests.
83
+ - **SQL client:** client for executing raw SQL queries.
84
+ - **Redis client:** client for working with Redis with automatic JSON (de)serialization.
85
+ - **GraphQL client:** client for executing GraphQL requests.
86
+ - **JSON Schema validation:** function to validate API responses or test artifacts with support for soft-assert and strict mode.
87
+
88
+ ## 👥 Ideal for
89
+
90
+ - **QA Engineers** — automate testing of APIs, databases and web services
91
+ - **Test Automation specialists** — get a ready toolkit for comprehensive testing
92
+
93
+ ## 🚀 Quick start
94
+
95
+ ### 1️⃣ Installation
96
+
97
+ ```bash
98
+ pip install qapytest
99
+ ```
100
+
101
+ ### 2️⃣ Your first powerful test
102
+
103
+ ```python
104
+ from qapytest import step, attach, soft_assert, HttpClient, SqlClient
105
+
106
+ def test_comprehensive_api_validation():
107
+ # Structured steps for readability
108
+ with step('🌐 Testing API endpoint'):
109
+ client = HttpClient(base_url="https://api.example.com")
110
+ response = client.get("/users/1")
111
+ assert response.status_code == 200
112
+
113
+ # Add artifacts for debugging
114
+ attach(response.text, 'api_response.json')
115
+
116
+ # Soft assertions - collect all failures
117
+ soft_assert(response.json()['id'] == 1, 'User ID check')
118
+ soft_assert(response.json()['active'], 'User is active')
119
+
120
+ # Database integration
121
+ with step('🗄️ Validate data in DB'):
122
+ db = SqlClient("postgresql://user:pass@localhost/db")
123
+ user_data = db.fetch_data("SELECT * FROM users WHERE id = 1")
124
+ assert len(user_data) == 1
125
+ ```
126
+
127
+ ### 3️⃣ Run with beautiful reports
128
+
129
+ ```bash
130
+ pytest --report-html
131
+ # Open report.html 🎨
132
+ ```
133
+
134
+ ## 🔌 Built-in clients — everything QA needs
135
+
136
+ ### 🌐 HttpClient — HTTP testing on steroids
137
+ ```python
138
+ client = HttpClient(base_url="https://api.example.com", timeout=30)
139
+ response = client.post("/auth/login", json={"username": "test"})
140
+ # Automatic logging of requests/responses + timing + headers
141
+ ```
142
+
143
+ ### 🗄️ SqlClient — Direct DB access
144
+ ```python
145
+ db = SqlClient("postgresql://localhost/testdb")
146
+ users = db.fetch_data("SELECT * FROM users WHERE active = true")
147
+ db.execute_and_commit("UPDATE users SET last_login = NOW() WHERE id = 1")
148
+ ```
149
+
150
+ ### 📊 GraphQL client — Modern APIs with minimal effort
151
+ ```python
152
+ gql = GraphQLClient("https://api.github.com/graphql",
153
+ headers={"Authorization": "Bearer token"})
154
+ result = gql.execute("query { viewer { login } }")
155
+ ```
156
+
157
+ ### 🔴 RedisClient — Caching and sessions under control
158
+ ```python
159
+ redis = RedisClient(host="localhost", port=6379)
160
+ redis.set_value("session:123", {"user_id": 1, "expires": "2024-01-01"})
161
+ session_data = redis.get_value("session:123") # Automatic JSON serialization!
162
+ ```
163
+
164
+ ## 🎛️ Core testing tools
165
+
166
+ ### 📝 Structured steps
167
+ ```python
168
+ with step('🔍 Check authorization'):
169
+ with step('Send login request'):
170
+ response = client.post("/login", json=creds)
171
+ with step('Validate token'):
172
+ assert "token" in response.json()
173
+ ```
174
+
175
+ ### 🎯 Soft Assertions — collect all failures
176
+ ```python
177
+ soft_assert(user.id == 1, 'User ID')
178
+ soft_assert(user.active, 'Active status')
179
+ soft_assert('admin' == user.roles, 'Access rights')
180
+ # The test will continue and show all failures together!
181
+ ```
182
+
183
+ ### 📎 Attachments — full context
184
+ ```python
185
+ attach(response.json(), 'server response')
186
+ attach(screenshot_bytes, 'error page')
187
+ attach(content, 'application', mime='text/plain')
188
+ ```
189
+
190
+ ### ✅ JSON Schema validation
191
+ ```python
192
+ # Strict validation — stop the test on schema validation error
193
+ validate_json(api_response, schema_path="user_schema.json", strict=True)
194
+
195
+ # Soft mode — collect all schema errors and continue test execution
196
+ validate_json(api_response, schema=user_schema, strict=False)
197
+ ```
198
+
199
+ More about the API on the [documentation page](./docs/API.md).
200
+
201
+ ## Test markers
202
+
203
+ QaPyTest also supports custom pytest markers to improve reporting:
204
+
205
+ - **`@pytest.mark.title("Custom Test Name")`** : sets a custom test name in the HTML report
206
+ - **`@pytest.mark.component("API", "Database")`** : adds component tags to the test
207
+
208
+ ### Example usage of markers
209
+
210
+ ```python
211
+ import pytest
212
+
213
+ @pytest.mark.title("User authorization check")
214
+ @pytest.mark.component("Auth", "API")
215
+ def test_user_login():
216
+ # test code
217
+ pass
218
+ ```
219
+
220
+ ## ⚙️ CLI options
221
+
222
+ - **`--env-file`** : path to an `.env` file with environment settings (default — `./.env`).
223
+ - **`--env-override`** : if set, values from the `.env` file will override existing environment variables.
224
+ - **`--report-html [PATH]`** : create a self-contained HTML report; optionally specify a path (default — `report.html`).
225
+ - **`--report-title NAME`** : set the HTML report title.
226
+ - **`--report-theme {light,dark,auto}`** : choose the report theme: `light`, `dark` or `auto` (default).
227
+ - **`--max-attachment-bytes N`** : maximum size of an attachment (in bytes) that will be inlined in the HTML; larger files will be truncated.
228
+
229
+ More about CLI options on the [documentation page](./docs/CLI.md).
230
+
231
+ ## 📑 License
232
+
233
+ This project is distributed under the [license](./LICENSE).
@@ -0,0 +1,180 @@
1
+ # QaPyTest
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/qapytest.svg)](https://pypi.org/project/qapytest/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/qapytest.svg)](https://pypi.org/project/qapytest/)
5
+ [![License](https://img.shields.io/github/license/o73k51i/qapytest.svg)](https://github.com/o73k51i/qapytest/blob/main/LICENSE)
6
+ [![Downloads](https://img.shields.io/pypi/dm/qapytest.svg)](https://pypi.org/project/qapytest/)
7
+ [![GitHub stars](https://img.shields.io/github/stars/o73k51i/qapytest.svg?style=social)](https://github.com/o73k51i/qapytest)
8
+
9
+ `QaPyTest` — a powerful testing framework based on pytest, specifically designed for QA engineers.
10
+ Turn your ordinary tests into detailed, structured reports with built-in HTTP, SQL, Redis and GraphQL clients.
11
+
12
+ 🎯 **QA made for QA** — every feature is designed for real testing and debugging needs.
13
+
14
+ ## ⚡ Why QaPyTest?
15
+
16
+ - **🚀 Ready to use:** Install → run → get a beautiful report
17
+ - **🔧 Built-in clients:** HTTP, SQL, Redis, GraphQL — all in one package
18
+ - **📊 Professional reports:** HTML reports with attachments and logs
19
+ - **🎯 Soft assertions:** Collect multiple failures in one run instead of stopping at the first
20
+ - **📝 Structured steps:** Make your tests self-documenting
21
+ - **🔍 Debugging friendly:** Full traceability of every action in the test
22
+
23
+ ## ⚙️ Key features
24
+
25
+ - **HTML report generation:** simple report at `report.html`.
26
+ - **Soft assertions:** allow collecting multiple failures in a single run without immediately ending the test.
27
+ - **Advanced steps:** structured logging of test steps for better report readability.
28
+ - **Attachments:** ability to add files, logs and screenshots to test reports.
29
+ - **HTTP client:** client for performing HTTP requests.
30
+ - **SQL client:** client for executing raw SQL queries.
31
+ - **Redis client:** client for working with Redis with automatic JSON (de)serialization.
32
+ - **GraphQL client:** client for executing GraphQL requests.
33
+ - **JSON Schema validation:** function to validate API responses or test artifacts with support for soft-assert and strict mode.
34
+
35
+ ## 👥 Ideal for
36
+
37
+ - **QA Engineers** — automate testing of APIs, databases and web services
38
+ - **Test Automation specialists** — get a ready toolkit for comprehensive testing
39
+
40
+ ## 🚀 Quick start
41
+
42
+ ### 1️⃣ Installation
43
+
44
+ ```bash
45
+ pip install qapytest
46
+ ```
47
+
48
+ ### 2️⃣ Your first powerful test
49
+
50
+ ```python
51
+ from qapytest import step, attach, soft_assert, HttpClient, SqlClient
52
+
53
+ def test_comprehensive_api_validation():
54
+ # Structured steps for readability
55
+ with step('🌐 Testing API endpoint'):
56
+ client = HttpClient(base_url="https://api.example.com")
57
+ response = client.get("/users/1")
58
+ assert response.status_code == 200
59
+
60
+ # Add artifacts for debugging
61
+ attach(response.text, 'api_response.json')
62
+
63
+ # Soft assertions - collect all failures
64
+ soft_assert(response.json()['id'] == 1, 'User ID check')
65
+ soft_assert(response.json()['active'], 'User is active')
66
+
67
+ # Database integration
68
+ with step('🗄️ Validate data in DB'):
69
+ db = SqlClient("postgresql://user:pass@localhost/db")
70
+ user_data = db.fetch_data("SELECT * FROM users WHERE id = 1")
71
+ assert len(user_data) == 1
72
+ ```
73
+
74
+ ### 3️⃣ Run with beautiful reports
75
+
76
+ ```bash
77
+ pytest --report-html
78
+ # Open report.html 🎨
79
+ ```
80
+
81
+ ## 🔌 Built-in clients — everything QA needs
82
+
83
+ ### 🌐 HttpClient — HTTP testing on steroids
84
+ ```python
85
+ client = HttpClient(base_url="https://api.example.com", timeout=30)
86
+ response = client.post("/auth/login", json={"username": "test"})
87
+ # Automatic logging of requests/responses + timing + headers
88
+ ```
89
+
90
+ ### 🗄️ SqlClient — Direct DB access
91
+ ```python
92
+ db = SqlClient("postgresql://localhost/testdb")
93
+ users = db.fetch_data("SELECT * FROM users WHERE active = true")
94
+ db.execute_and_commit("UPDATE users SET last_login = NOW() WHERE id = 1")
95
+ ```
96
+
97
+ ### 📊 GraphQL client — Modern APIs with minimal effort
98
+ ```python
99
+ gql = GraphQLClient("https://api.github.com/graphql",
100
+ headers={"Authorization": "Bearer token"})
101
+ result = gql.execute("query { viewer { login } }")
102
+ ```
103
+
104
+ ### 🔴 RedisClient — Caching and sessions under control
105
+ ```python
106
+ redis = RedisClient(host="localhost", port=6379)
107
+ redis.set_value("session:123", {"user_id": 1, "expires": "2024-01-01"})
108
+ session_data = redis.get_value("session:123") # Automatic JSON serialization!
109
+ ```
110
+
111
+ ## 🎛️ Core testing tools
112
+
113
+ ### 📝 Structured steps
114
+ ```python
115
+ with step('🔍 Check authorization'):
116
+ with step('Send login request'):
117
+ response = client.post("/login", json=creds)
118
+ with step('Validate token'):
119
+ assert "token" in response.json()
120
+ ```
121
+
122
+ ### 🎯 Soft Assertions — collect all failures
123
+ ```python
124
+ soft_assert(user.id == 1, 'User ID')
125
+ soft_assert(user.active, 'Active status')
126
+ soft_assert('admin' == user.roles, 'Access rights')
127
+ # The test will continue and show all failures together!
128
+ ```
129
+
130
+ ### 📎 Attachments — full context
131
+ ```python
132
+ attach(response.json(), 'server response')
133
+ attach(screenshot_bytes, 'error page')
134
+ attach(content, 'application', mime='text/plain')
135
+ ```
136
+
137
+ ### ✅ JSON Schema validation
138
+ ```python
139
+ # Strict validation — stop the test on schema validation error
140
+ validate_json(api_response, schema_path="user_schema.json", strict=True)
141
+
142
+ # Soft mode — collect all schema errors and continue test execution
143
+ validate_json(api_response, schema=user_schema, strict=False)
144
+ ```
145
+
146
+ More about the API on the [documentation page](./docs/API.md).
147
+
148
+ ## Test markers
149
+
150
+ QaPyTest also supports custom pytest markers to improve reporting:
151
+
152
+ - **`@pytest.mark.title("Custom Test Name")`** : sets a custom test name in the HTML report
153
+ - **`@pytest.mark.component("API", "Database")`** : adds component tags to the test
154
+
155
+ ### Example usage of markers
156
+
157
+ ```python
158
+ import pytest
159
+
160
+ @pytest.mark.title("User authorization check")
161
+ @pytest.mark.component("Auth", "API")
162
+ def test_user_login():
163
+ # test code
164
+ pass
165
+ ```
166
+
167
+ ## ⚙️ CLI options
168
+
169
+ - **`--env-file`** : path to an `.env` file with environment settings (default — `./.env`).
170
+ - **`--env-override`** : if set, values from the `.env` file will override existing environment variables.
171
+ - **`--report-html [PATH]`** : create a self-contained HTML report; optionally specify a path (default — `report.html`).
172
+ - **`--report-title NAME`** : set the HTML report title.
173
+ - **`--report-theme {light,dark,auto}`** : choose the report theme: `light`, `dark` or `auto` (default).
174
+ - **`--max-attachment-bytes N`** : maximum size of an attachment (in bytes) that will be inlined in the HTML; larger files will be truncated.
175
+
176
+ More about CLI options on the [documentation page](./docs/CLI.md).
177
+
178
+ ## 📑 License
179
+
180
+ This project is distributed under the [license](./LICENSE).