qase-python-commons 4.1.10__tar.gz → 5.0.1__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 (54) hide show
  1. qase_python_commons-5.0.1/PKG-INFO +462 -0
  2. qase_python_commons-5.0.1/README.md +427 -0
  3. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/pyproject.toml +1 -1
  4. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/client/api_v2_client.py +5 -3
  5. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/config.py +14 -0
  6. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/config/qaseconfig.py +25 -1
  7. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/config/testops.py +58 -1
  8. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/result.py +41 -0
  9. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/reporters/__init__.py +2 -0
  10. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/reporters/core.py +28 -4
  11. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/reporters/testops.py +1 -1
  12. qase_python_commons-5.0.1/src/qase/commons/reporters/testops_multi.py +335 -0
  13. qase_python_commons-5.0.1/src/qase_python_commons.egg-info/PKG-INFO +462 -0
  14. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase_python_commons.egg-info/SOURCES.txt +1 -0
  15. qase_python_commons-4.1.10/PKG-INFO +0 -49
  16. qase_python_commons-4.1.10/README.md +0 -14
  17. qase_python_commons-4.1.10/src/qase_python_commons.egg-info/PKG-INFO +0 -49
  18. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/setup.cfg +0 -0
  19. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/__init__.py +0 -0
  20. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/__init__.py +0 -0
  21. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/client/api_v1_client.py +0 -0
  22. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/client/base_api_client.py +0 -0
  23. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/exceptions/reporter.py +0 -0
  24. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/loader.py +0 -0
  25. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/logger.py +0 -0
  26. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/__init__.py +0 -0
  27. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/attachment.py +0 -0
  28. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/basemodel.py +0 -0
  29. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/config/api.py +0 -0
  30. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/config/batch.py +0 -0
  31. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/config/connection.py +0 -0
  32. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/config/framework.py +0 -0
  33. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/config/plan.py +0 -0
  34. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/config/report.py +0 -0
  35. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/config/run.py +0 -0
  36. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/external_link.py +0 -0
  37. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/relation.py +0 -0
  38. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/run.py +0 -0
  39. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/runtime.py +0 -0
  40. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/models/step.py +0 -0
  41. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/profilers/__init__.py +0 -0
  42. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/profilers/db.py +0 -0
  43. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/profilers/network.py +0 -0
  44. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/profilers/sleep.py +0 -0
  45. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/reporters/report.py +0 -0
  46. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/status_mapping/__init__.py +0 -0
  47. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/status_mapping/status_mapping.py +0 -0
  48. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/util/__init__.py +0 -0
  49. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/util/host_data.py +0 -0
  50. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/utils.py +0 -0
  51. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase/commons/validators/base.py +0 -0
  52. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase_python_commons.egg-info/dependency_links.txt +0 -0
  53. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase_python_commons.egg-info/requires.txt +0 -0
  54. {qase_python_commons-4.1.10 → qase_python_commons-5.0.1}/src/qase_python_commons.egg-info/top_level.txt +0 -0
@@ -0,0 +1,462 @@
1
+ Metadata-Version: 2.4
2
+ Name: qase-python-commons
3
+ Version: 5.0.1
4
+ Summary: A library for Qase TestOps and Qase Report
5
+ Author-email: Qase Team <support@qase.io>
6
+ Project-URL: Homepage, https://github.com/qase-tms/qase-python/tree/main/qase-python-commons
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: Programming Language :: Python
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Topic :: Software Development :: Quality Assurance
12
+ Classifier: Topic :: Software Development :: Testing
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ Requires-Dist: certifi>=2024.2.2
23
+ Requires-Dist: attrs>=23.2.0
24
+ Requires-Dist: qase-api-client~=2.0.3
25
+ Requires-Dist: qase-api-v2-client~=2.0.3
26
+ Requires-Dist: more_itertools
27
+ Provides-Extra: testing
28
+ Requires-Dist: pytest; extra == "testing"
29
+ Requires-Dist: pytest-cov; extra == "testing"
30
+ Requires-Dist: mock; extra == "testing"
31
+ Requires-Dist: more_itertools; extra == "testing"
32
+ Requires-Dist: requests; extra == "testing"
33
+ Requires-Dist: urllib3; extra == "testing"
34
+ Requires-Dist: freezegun; extra == "testing"
35
+
36
+ # Qase Python Commons
37
+
38
+ ## Description
39
+
40
+ This module is an SDK for developing test reporters for Qase TMS.
41
+ It's using `qase-api-client` as an API client, and all Qase Python reporters are, in turn,
42
+ using this package.
43
+ You should use it if you're developing your own test reporter for a special-purpose framework.
44
+
45
+ To report results from tests using a popular framework or test runner,
46
+ don't install this module directly and
47
+ use the corresponding reporter module instead:
48
+
49
+ * [Pytest](https://github.com/qase-tms/qase-python/tree/main/qase-pytest#readme)
50
+ * [Behave](https://github.com/qase-tms/qase-python/tree/main/qase-behave#readme)
51
+ * [Robot Framework](https://github.com/qase-tms/qase-python/tree/main/qase-robotframework#readme)
52
+ * [Tavern](https://github.com/qase-tms/qase-python/tree/main/qase-tavern#readme)
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ pip install qase-python-commons
58
+ ```
59
+
60
+ ## Configuration
61
+
62
+ Qase Python Reporters can be configured in multiple ways:
63
+
64
+ * using a config file `qase.config.json`
65
+ * using environment variables
66
+ * using command line options (for frameworks that support it, like pytest and tavern)
67
+
68
+ Environment variables override the values given in the config file,
69
+ and command line options override both other values.
70
+
71
+ All configuration options are listed in the tables below:
72
+
73
+ ### Common Configuration
74
+
75
+ | Description | Config file | Environment variable | Default value | Required | Possible values |
76
+ |-----------------------------------------------------------------------------------------------------------------------|----------------------------|---------------------------------|-----------------------------------------|----------|----------------------------|
77
+ | **Common** | | | | | |
78
+ | Mode of reporter | `mode` | `QASE_MODE` | `off` | No | `testops`, `testops_multi`, `report`, `off` |
79
+ | Fallback mode of reporter | `fallback` | `QASE_FALLBACK` | `off` | No | `testops`, `testops_multi`, `report`, `off` |
80
+ | Environment | `environment` | `QASE_ENVIRONMENT` | undefined | No | Any string |
81
+ | Root suite | `rootSuite` | `QASE_ROOT_SUITE` | undefined | No | Any string |
82
+ | Enable debug logs | `debug` | `QASE_DEBUG` | `False` | No | `True`, `False` |
83
+ | Execution plan path | `executionPlan.path` | `QASE_EXECUTION_PLAN_PATH` | `./build/qase-execution-plan.json` | No | Any string |
84
+ | Exclude parameters from test results | `excludeParams` | `QASE_EXCLUDE_PARAMS` | undefined | No | Comma-separated list of parameter names |
85
+ | Map test result statuses to different values (format: `fromStatus=toStatus`) | `statusMapping` | `QASE_STATUS_MAPPING` | undefined | No | Object mapping statuses (e.g., `{"invalid": "failed", "skipped": "passed"}`) |
86
+ | **Logging configuration** | | | | | |
87
+ | Enable/disable console output for reporter logs | `logging.console` | `QASE_LOGGING_CONSOLE` | `True` | No | `True`, `False` |
88
+ | Enable/disable file output for reporter logs | `logging.file` | `QASE_LOGGING_FILE` | Same as `debug` setting | No | `True`, `False` |
89
+ | **Qase Report configuration** | | | | | |
90
+ | Driver used for report mode | `report.driver` | `QASE_REPORT_DRIVER` | `local` | No | `local` |
91
+ | Path to save the report | `report.connection.path` | `QASE_REPORT_CONNECTION_PATH` | `./build/qase-report` | No | Any string |
92
+ | Local report format | `report.connection.format` | `QASE_REPORT_CONNECTION_FORMAT` | `json` | No | `json`, `jsonp` |
93
+ | **Qase TestOps configuration (single project)** | | | | | |
94
+ | Token for [API access](https://developers.qase.io/#authentication) | `testops.api.token` | `QASE_TESTOPS_API_TOKEN` | undefined | Yes* | Any string |
95
+ | Qase API host. For enterprise users, specify address: `example.qase.io` | `testops.api.host` | `QASE_TESTOPS_API_HOST` | `qase.io` | No | Any string |
96
+ | Code of your project, which you can take from the URL: `https://app.qase.io/project/DEMOTR` - `DEMOTR` is the project code | `testops.project` | `QASE_TESTOPS_PROJECT` | undefined | Yes* | Any string |
97
+ | Qase test run ID | `testops.run.id` | `QASE_TESTOPS_RUN_ID` | undefined | No | Any integer |
98
+ | Qase test run title | `testops.run.title` | `QASE_TESTOPS_RUN_TITLE` | `Automated run <Current date and time>` | No | Any string |
99
+ | Qase test run description | `testops.run.description` | `QASE_TESTOPS_RUN_DESCRIPTION` | `<Framework name> automated run` | No | Any string |
100
+ | Qase test run complete | `testops.run.complete` | `QASE_TESTOPS_RUN_COMPLETE` | `True` | No | `True`, `False` |
101
+ | Array of tags to be added to the test run | `testops.run.tags` | `QASE_TESTOPS_RUN_TAGS` | `[]` | No | Array of strings |
102
+ | External link to associate with test run (e.g., Jira ticket) | `testops.run.externalLink` | `QASE_TESTOPS_RUN_EXTERNAL_LINK` | undefined | No | JSON object with `type` (`jiraCloud` or `jiraServer`) and `link` (e.g., `PROJ-123`) |
103
+ | Qase test plan ID | `testops.plan.id` | `QASE_TESTOPS_PLAN_ID` | undefined | No | Any integer |
104
+ | Size of batch for sending test results | `testops.batch.size` | `QASE_TESTOPS_BATCH_SIZE` | `200` | No | Any integer (1 to 2000) |
105
+ | Enable defects for failed test cases | `testops.defect` | `QASE_TESTOPS_DEFECT` | `False` | No | `True`, `False` |
106
+ | Filter test results by status (comma-separated list of statuses to exclude from reporting) | `testops.statusFilter` | `QASE_TESTOPS_STATUS_FILTER` | undefined | No | Array of strings (`passed`, `failed`, `skipped`, `invalid`) |
107
+ | Configuration values to create/find in groups (format: `group1=value1,group2=value2`) | `testops.configurations.values` | `QASE_TESTOPS_CONFIGURATIONS_VALUES` | undefined | No | Array of objects with `name` and `value` fields |
108
+ | Create configuration groups if they don't exist | `testops.configurations.createIfNotExists` | `QASE_TESTOPS_CONFIGURATIONS_CREATE_IF_NOT_EXISTS` | `false` | No | `True`, `False` |
109
+ | Enable public report link generation and display after test run completion | `testops.showPublicReportLink` | `QASE_TESTOPS_SHOW_PUBLIC_REPORT_LINK` | `False` | No | `True`, `False` |
110
+ | **Qase TestOps Multi-Project configuration** | | | | | |
111
+ | Default project code for tests without explicit project mapping | `testops_multi.default_project` | `QASE_TESTOPS_MULTI_DEFAULT_PROJECT` | undefined | No | Any string (must match one of the project codes in `projects`) |
112
+ | Array of project configurations | `testops_multi.projects` | N/A (use config file) | `[]` | Yes** | Array of project configuration objects |
113
+ | Project code | `testops_multi.projects[].code` | N/A | undefined | Yes** | Any string |
114
+ | Project-specific test run title | `testops_multi.projects[].run.title` | N/A | `Automated Run <project_code> <Current date and time>` | No | Any string |
115
+ | Project-specific test run description | `testops_multi.projects[].run.description` | N/A | `Automated Run <project_code> <Current date and time>` | No | Any string |
116
+ | Project-specific test run complete | `testops_multi.projects[].run.complete` | N/A | `True` | No | `True`, `False` |
117
+ | Project-specific test run ID | `testops_multi.projects[].run.id` | N/A | undefined | No | Any integer |
118
+ | Project-specific test run tags | `testops_multi.projects[].run.tags` | N/A | `[]` | No | Array of strings |
119
+ | Project-specific external link | `testops_multi.projects[].run.externalLink` | N/A | undefined | No | JSON object with `type` and `link` |
120
+ | Project-specific test plan ID | `testops_multi.projects[].plan.id` | N/A | undefined | No | Any integer |
121
+ | Project-specific environment | `testops_multi.projects[].environment` | N/A | Uses global `environment` if not set | No | Any string or integer (environment ID) |
122
+
123
+ \* Required when using `testops` mode
124
+ \** Required when using `testops_multi` mode
125
+
126
+ ### Framework-Specific Configuration
127
+
128
+ #### Pytest
129
+
130
+ | Description | Config file | Environment variable | CLI option | Default value | Required | Possible values |
131
+ |------------------------------------------------|--------------------------------------|----------------------------------|------------------------------------|-----------------------------------------|----------|----------------------------|
132
+ | Capture logs | `framework.pytest.captureLogs` | `QASE_PYTEST_CAPTURE_LOGS` | `--qase-pytest-capture-logs` | `False` | No | `true`, `false` |
133
+ | XFail status for failed tests | `framework.pytest.xfailStatus.xfail` | `QASE_PYTEST_XFAIL_STATUS_XFAIL` | `--qase-pytest-xfail-status-xfail` | `Skipped` | No | Any string |
134
+ | XFail status for passed tests | `framework.pytest.xfailStatus.xpass` | `QASE_PYTEST_XFAIL_STATUS_XPASS` | `--qase-pytest-xfail-status-xpass` | `Passed` | No | Any string |
135
+
136
+ #### Behave
137
+
138
+ Behave reporter uses the same common configuration options. There are no framework-specific options for Behave.
139
+
140
+ #### Robot Framework
141
+
142
+ Robot Framework reporter uses the same common configuration options. There are no framework-specific options for Robot Framework.
143
+
144
+ #### Tavern
145
+
146
+ Tavern reporter uses the same common configuration options. There are no framework-specific options for Tavern.
147
+
148
+ ## Configuration Examples
149
+
150
+ ### Single Project Configuration (`testops` mode)
151
+
152
+ Example `qase.config.json` config:
153
+
154
+ ```json
155
+ {
156
+ "mode": "testops",
157
+ "fallback": "report",
158
+ "debug": false,
159
+ "environment": "local",
160
+ "excludeParams": ["password", "token"],
161
+ "statusMapping": {
162
+ "invalid": "failed",
163
+ "skipped": "passed"
164
+ },
165
+ "logging": {
166
+ "console": true,
167
+ "file": true
168
+ },
169
+ "report": {
170
+ "driver": "local",
171
+ "connection": {
172
+ "local": {
173
+ "path": "./build/qase-report",
174
+ "format": "json"
175
+ }
176
+ }
177
+ },
178
+ "testops": {
179
+ "api": {
180
+ "token": "<token>",
181
+ "host": "qase.io"
182
+ },
183
+ "project": "<project_code>",
184
+ "run": {
185
+ "title": "Regress run",
186
+ "description": "Regress run description",
187
+ "complete": true,
188
+ "tags": ["tag1", "tag2"],
189
+ "externalLink": {
190
+ "type": "jiraCloud",
191
+ "link": "PROJ-123"
192
+ }
193
+ },
194
+ "defect": false,
195
+ "batch": {
196
+ "size": 100
197
+ },
198
+ "statusFilter": ["passed", "skipped"],
199
+ "showPublicReportLink": true,
200
+ "configurations": {
201
+ "values": [
202
+ {
203
+ "name": "group1",
204
+ "value": "value1"
205
+ },
206
+ {
207
+ "name": "group2",
208
+ "value": "value2"
209
+ }
210
+ ],
211
+ "createIfNotExists": true
212
+ }
213
+ },
214
+ "framework": {
215
+ "pytest": {
216
+ "captureLogs": true,
217
+ "xfailStatus": {
218
+ "xfail": "Skipped",
219
+ "xpass": "Passed"
220
+ }
221
+ }
222
+ }
223
+ }
224
+ ```
225
+
226
+ ### Multi-Project Configuration (`testops_multi` mode)
227
+
228
+ Example `qase.config.json` config for multi-project reporting:
229
+
230
+ ```json
231
+ {
232
+ "mode": "testops_multi",
233
+ "fallback": "report",
234
+ "debug": false,
235
+ "environment": "local",
236
+ "logging": {
237
+ "console": true,
238
+ "file": false
239
+ },
240
+ "report": {
241
+ "driver": "local",
242
+ "connection": {
243
+ "local": {
244
+ "path": "./build/qase-report",
245
+ "format": "json"
246
+ }
247
+ }
248
+ },
249
+ "testops": {
250
+ "api": {
251
+ "token": "<token>",
252
+ "host": "qase.io"
253
+ },
254
+ "batch": {
255
+ "size": 100
256
+ },
257
+ "statusFilter": ["passed"],
258
+ "showPublicReportLink": true
259
+ },
260
+ "testops_multi": {
261
+ "default_project": "DEMO1",
262
+ "projects": [
263
+ {
264
+ "code": "DEMO1",
265
+ "run": {
266
+ "title": "DEMO1 Multi-Project Run",
267
+ "description": "Test run for DEMO1 project",
268
+ "complete": true,
269
+ "tags": ["staging", "regression"],
270
+ "externalLink": {
271
+ "type": "jiraCloud",
272
+ "link": "PROJ-123"
273
+ }
274
+ },
275
+ "plan": {
276
+ "id": 1
277
+ },
278
+ "environment": "staging"
279
+ },
280
+ {
281
+ "code": "DEMO2",
282
+ "run": {
283
+ "title": "DEMO2 Multi-Project Run",
284
+ "description": "Test run for DEMO2 project",
285
+ "complete": true,
286
+ "tags": ["production", "regression"]
287
+ },
288
+ "environment": "production"
289
+ }
290
+ ]
291
+ }
292
+ }
293
+ ```
294
+
295
+ ### Environment Variables Example
296
+
297
+ ```bash
298
+ # Common settings
299
+ export QASE_MODE="testops"
300
+ export QASE_FALLBACK="report"
301
+ export QASE_ENVIRONMENT="local"
302
+ export QASE_DEBUG="true"
303
+ export QASE_ROOT_SUITE="MyTestSuite"
304
+ export QASE_EXCLUDE_PARAMS="password,token"
305
+ export QASE_STATUS_MAPPING="invalid=failed,skipped=passed"
306
+
307
+ # Logging configuration
308
+ export QASE_LOGGING_CONSOLE="true"
309
+ export QASE_LOGGING_FILE="false"
310
+
311
+ # Report mode configuration
312
+ export QASE_REPORT_DRIVER="local"
313
+ export QASE_REPORT_CONNECTION_PATH="./build/qase-report"
314
+ export QASE_REPORT_CONNECTION_FORMAT="json"
315
+
316
+ # TestOps configuration (single project)
317
+ export QASE_TESTOPS_API_TOKEN="<token>"
318
+ export QASE_TESTOPS_API_HOST="qase.io"
319
+ export QASE_TESTOPS_PROJECT="DEMO"
320
+ export QASE_TESTOPS_RUN_TITLE="My Test Run"
321
+ export QASE_TESTOPS_RUN_DESCRIPTION="Test run description"
322
+ export QASE_TESTOPS_RUN_COMPLETE="true"
323
+ export QASE_TESTOPS_RUN_TAGS="tag1,tag2"
324
+ export QASE_TESTOPS_RUN_EXTERNAL_LINK='{"type":"jiraCloud","link":"PROJ-123"}'
325
+ export QASE_TESTOPS_PLAN_ID="1"
326
+ export QASE_TESTOPS_BATCH_SIZE="100"
327
+ export QASE_TESTOPS_DEFECT="false"
328
+ export QASE_TESTOPS_STATUS_FILTER="passed,skipped"
329
+ export QASE_TESTOPS_SHOW_PUBLIC_REPORT_LINK="true"
330
+
331
+ # TestOps configurations
332
+ export QASE_TESTOPS_CONFIGURATIONS_VALUES='[{"name":"browser","value":"chrome"},{"name":"os","value":"linux"}]'
333
+ export QASE_TESTOPS_CONFIGURATIONS_CREATE_IF_NOT_EXISTS="true"
334
+
335
+ # Pytest-specific
336
+ export QASE_PYTEST_CAPTURE_LOGS="true"
337
+ export QASE_PYTEST_XFAIL_STATUS_XFAIL="Skipped"
338
+ export QASE_PYTEST_XFAIL_STATUS_XPASS="Passed"
339
+
340
+ # Multi-project configuration (default project only)
341
+ export QASE_TESTOPS_MULTI_DEFAULT_PROJECT="DEMO1"
342
+ ```
343
+
344
+ ## Multi-Project Support
345
+
346
+ The multi-project feature allows you to send test results to multiple Qase projects simultaneously, with different test case IDs for each project. This is useful when:
347
+
348
+ * You need to report the same test to different projects
349
+ * Different projects track the same functionality with different test case IDs
350
+ * You want to maintain separate test runs for different environments or teams
351
+
352
+ ### How It Works
353
+
354
+ 1. Configure multiple projects in `testops_multi.projects` array
355
+ 2. Each project can have its own run configuration (title, description, tags, plan, environment)
356
+ 3. Use framework-specific annotations to map test cases to projects:
357
+ * **Pytest**: Use `@qase.project_id()` decorator
358
+ * **Behave**: Use `@qase.project_id.PROJECT_CODE:IDS` tag format
359
+ * **Robot Framework**: Use `Q-PROJECT.PROJECT_CODE-IDS` tag format
360
+ * **Tavern**: Use `QaseProjectID.PROJECT_CODE=IDS` format in test names
361
+ 4. Tests without explicit project mapping will be sent to the `default_project`
362
+
363
+ ### Framework-Specific Documentation
364
+
365
+ For detailed framework-specific documentation on multi-project support, see:
366
+
367
+ * **[Pytest Multi-Project Guide](../qase-pytest/docs/MULTI_PROJECT.md)** - Detailed guide for using multi-project support with Pytest, including decorator usage, parametrized tests, and test classes
368
+ * **[Behave Multi-Project Guide](../qase-behave/docs/MULTI_PROJECT.md)** - Detailed guide for using multi-project support with Behave, including tag formats, feature-level tags, and scenario mapping
369
+ * **[Robot Framework Multi-Project Guide](../qase-robotframework/docs/MULTI_PROJECT.md)** - Detailed guide for using multi-project support with Robot Framework, including tag formats, suite-level tags, and parameter handling
370
+ * **[Tavern Multi-Project Guide](../qase-tavern/docs/MULTI_PROJECT.md)** - Detailed guide for using multi-project support with Tavern, including test name formats, extraction rules, and troubleshooting
371
+
372
+ ### Example Usage
373
+
374
+ For detailed examples, see the [multi-project examples directory](../examples/multiproject/).
375
+
376
+ ## Status Mapping
377
+
378
+ You can map test result statuses to different values using the `statusMapping` configuration option. This is useful when you want to change how certain statuses are reported to Qase.
379
+
380
+ Example:
381
+
382
+ ```json
383
+ {
384
+ "statusMapping": {
385
+ "invalid": "failed",
386
+ "skipped": "passed"
387
+ }
388
+ }
389
+ ```
390
+
391
+ This will map:
392
+
393
+ * `invalid` status → `failed` in Qase
394
+ * `skipped` status → `passed` in Qase
395
+
396
+ ## Status Filtering
397
+
398
+ You can filter out test results by status using the `testops.statusFilter` configuration option. Results with statuses in the filter list will not be sent to Qase.
399
+
400
+ Example:
401
+
402
+ ```json
403
+ {
404
+ "testops": {
405
+ "statusFilter": ["passed", "skipped"]
406
+ }
407
+ }
408
+ ```
409
+
410
+ This will exclude all `passed` and `skipped` results from being reported to Qase.
411
+
412
+ ## External Links
413
+
414
+ You can associate external links (e.g., Jira tickets) with test runs using the `testops.run.externalLink` configuration.
415
+
416
+ Example:
417
+
418
+ ```json
419
+ {
420
+ "testops": {
421
+ "run": {
422
+ "externalLink": {
423
+ "type": "jiraCloud",
424
+ "link": "PROJ-123"
425
+ }
426
+ }
427
+ }
428
+ }
429
+ ```
430
+
431
+ Supported types:
432
+
433
+ * `jiraCloud` - For Jira Cloud
434
+ * `jiraServer` - For Jira Server
435
+
436
+ ## Configurations
437
+
438
+ You can specify test run configurations that will be created or found in Qase TestOps.
439
+
440
+ Example:
441
+
442
+ ```json
443
+ {
444
+ "testops": {
445
+ "configurations": {
446
+ "values": [
447
+ {
448
+ "name": "browser",
449
+ "value": "chrome"
450
+ },
451
+ {
452
+ "name": "os",
453
+ "value": "linux"
454
+ }
455
+ ],
456
+ "createIfNotExists": true
457
+ }
458
+ }
459
+ }
460
+ ```
461
+
462
+ If `createIfNotExists` is `true`, configuration groups and values will be created automatically if they don't exist.