testit-adapter-pytest 4.2.8__py3-none-any.whl

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.
File without changes
@@ -0,0 +1,33 @@
1
+ from uuid import uuid4
2
+
3
+ from testit_python_commons.services import Utils, TmsPluginManager
4
+
5
+
6
+ class FixtureContext:
7
+ def __init__(self, fixture_function, parent_uuid=None, name=None):
8
+ self._fixture_function = fixture_function
9
+ self._parent_uuid = parent_uuid
10
+ self.__title = name if name else fixture_function.__name__
11
+ self.__description = fixture_function.__doc__
12
+ self._uuid = uuid4()
13
+ self.parameters = None
14
+
15
+ def __call__(self, *args, **kwargs):
16
+ self.parameters = Utils.get_function_parameters(self._fixture_function, *args, **kwargs)
17
+
18
+ with self:
19
+ return self._fixture_function(*args, **kwargs)
20
+
21
+ def __enter__(self):
22
+ TmsPluginManager.get_plugin_manager().hook.start_fixture(
23
+ parent_uuid=self._parent_uuid,
24
+ uuid=self._uuid,
25
+ title=self.__title,
26
+ parameters=self.parameters)
27
+
28
+ def __exit__(self, exc_type, exc_val, exc_tb):
29
+ TmsPluginManager.get_plugin_manager().hook.stop_fixture(
30
+ uuid=self._uuid,
31
+ exc_type=exc_type,
32
+ exc_val=exc_val,
33
+ exc_tb=exc_tb)
@@ -0,0 +1,388 @@
1
+ import pickle
2
+ from importlib.metadata import metadata
3
+ from uuid import uuid4
4
+
5
+ from packaging import version
6
+
7
+ import pytest
8
+
9
+ import testit_python_commons.services as adapter
10
+ from testit_python_commons.models.outcome_type import OutcomeType
11
+ from testit_python_commons.models.status_type import StatusType
12
+ from testit_python_commons.models.fixture import FixtureResult, FixturesContainer
13
+ from testit_python_commons.services import AdapterManager, StepManager, FixtureManager
14
+ from testit_python_commons.services.logger import adapter_logger
15
+
16
+ import testit_adapter_pytest.utils as utils
17
+ from testit_adapter_pytest.fixture_context import FixtureContext
18
+
19
+
20
+ STATUS_TYPE = {
21
+ 'passed': StatusType.SUCCEEDED,
22
+ 'failed': StatusType.FAILED,
23
+ 'xfailed': StatusType.FAILED,
24
+ 'skipped': StatusType.INCOMPLETE,
25
+ }
26
+ STEP_STATUS = {
27
+ 'passed': OutcomeType.PASSED,
28
+ 'failed': OutcomeType.FAILED,
29
+ 'skipped': OutcomeType.SKIPPED,
30
+ }
31
+
32
+
33
+ class ItemCache:
34
+ def __init__(self):
35
+ self._items = dict()
36
+
37
+ def get(self, _id):
38
+ return self._items.get(id(_id))
39
+
40
+ def push(self, _id):
41
+ return self._items.setdefault(id(_id), uuid4())
42
+
43
+ def pop(self, _id):
44
+ return self._items.pop(id(_id), None)
45
+
46
+
47
+ class SeparationOfTests:
48
+ def __init__(self):
49
+ self._selected_items = []
50
+ self._deselected_items = []
51
+
52
+ def add_item_to_selected_items(self, item):
53
+ self._selected_items.append(item)
54
+
55
+ return self
56
+
57
+ def add_item_to_deselected_items(self, item):
58
+ self._deselected_items.append(item)
59
+
60
+ return self
61
+
62
+ def get_selected_items(self) -> list:
63
+ return self._selected_items
64
+
65
+ def get_deselected_items(self) -> list:
66
+ return self._deselected_items
67
+
68
+
69
+ class TmsListener(object):
70
+ __executable_test = None
71
+ __pytest_info = None
72
+ __pytest_check_info = None
73
+ __failures = None
74
+
75
+ def __init__(self, adapter_manager: AdapterManager, step_manager: StepManager, fixture_manager: FixtureManager):
76
+ self.__adapter_manager = adapter_manager
77
+ self.__step_manager = step_manager
78
+ self.__fixture_manager = fixture_manager
79
+ self._cache = ItemCache()
80
+
81
+ @pytest.hookimpl
82
+ def pytest_configure(self, config):
83
+ self.__pytest_info = metadata("pytest")
84
+
85
+ if hasattr(config, "workerinput"):
86
+ config.test_run_id = pickle.loads(config.workerinput["test_run_id"])
87
+ elif not hasattr(config, "test_run_id"):
88
+ config.test_run_id = self.__adapter_manager.get_test_run_id()
89
+
90
+ self.__adapter_manager.set_test_run_id(config.test_run_id)
91
+
92
+ @pytest.hookimpl
93
+ def pytest_configure_node(self, node):
94
+ if hasattr(node.config, "test_run_id"):
95
+ node.workerinput["test_run_id"] = pickle.dumps(node.config.test_run_id)
96
+
97
+ @adapter.hookimpl
98
+ def get_pytest_check_outcome(self):
99
+ if self.__pytest_check_info:
100
+ if version.parse(self.__pytest_check_info.version) < version.parse("1.1.0"):
101
+ from pytest_check import check_methods as logs
102
+ else:
103
+ from pytest_check import check_log as logs
104
+
105
+ failures = logs.get_failures()
106
+
107
+ if failures and self.__failures != failures:
108
+ self.__failures = failures[:]
109
+ return 'Failed'
110
+ return 'Passed'
111
+
112
+ @pytest.hookimpl
113
+ def pytest_collection_modifyitems(self, config, items):
114
+ self.__add_pytest_check_info(config.pluginmanager.list_plugin_distinfo())
115
+
116
+ resolved_autotests = self.__adapter_manager.get_autotests_for_launch()
117
+ separation_of_tests = self.__get_separation_of_tests(items, resolved_autotests)
118
+
119
+ if resolved_autotests:
120
+ if not separation_of_tests.get_selected_items():
121
+ raise Exception('The specified tests were not found!')
122
+
123
+ config.hook.pytest_deselected(items=separation_of_tests.get_deselected_items())
124
+ items[:] = separation_of_tests.get_selected_items()
125
+
126
+ def __add_pytest_check_info(self, plugin_info):
127
+ for plugin, dist in plugin_info:
128
+ if 'pytest-check' == dist.project_name:
129
+ self.__pytest_check_info = dist
130
+ return
131
+
132
+ @classmethod
133
+ @adapter_logger
134
+ def __get_separation_of_tests(cls, items, resolved_autotests) -> SeparationOfTests:
135
+ separation_of_tests = SeparationOfTests()
136
+ index = 0
137
+
138
+ for item in items:
139
+ if hasattr(item.function, 'test_external_id'):
140
+ item.test_external_id = item.function.test_external_id
141
+ else:
142
+ item.test_external_id = utils.get_hash(item.parent.nodeid + item.function.__name__)
143
+
144
+ if item.own_markers:
145
+ for mark in item.own_markers:
146
+ if mark.name == 'parametrize':
147
+ if not hasattr(item, 'array_parametrize_mark_id'):
148
+ item.array_parametrize_mark_id = []
149
+ item.array_parametrize_mark_id.append(
150
+ item.own_markers.index(mark))
151
+
152
+ params = utils.get_all_parameters(item)
153
+ item.test_external_id = utils.collect_parameters_in_string_attribute(
154
+ item.test_external_id,
155
+ params)
156
+
157
+ item.index = index
158
+ item_id = items.index(item)
159
+ index = index + 1 if len(items) > item_id + 1 and items[item_id + 1].originalname == item.originalname \
160
+ else 0
161
+
162
+ if cls.__check_external_id_in_resolved_autotests(item.test_external_id, resolved_autotests):
163
+ separation_of_tests.add_item_to_selected_items(item)
164
+ else:
165
+ separation_of_tests.add_item_to_deselected_items(item)
166
+
167
+ return separation_of_tests
168
+
169
+ @staticmethod
170
+ @adapter_logger
171
+ def __check_external_id_in_resolved_autotests(external_id: str, resolved_autotests: dict) -> bool:
172
+ return resolved_autotests is not None and external_id in resolved_autotests
173
+
174
+ @pytest.hookimpl(tryfirst=True)
175
+ def pytest_runtest_protocol(self, item):
176
+ self.__executable_test = utils.form_test(item)
177
+ self.__adapter_manager.on_running_started()
178
+
179
+ @pytest.hookimpl(hookwrapper=True)
180
+ def pytest_runtest_setup(self, item):
181
+ if not self.__executable_test:
182
+ return
183
+
184
+ yield
185
+
186
+ self._update_fixtures_external_ids(item)
187
+
188
+ @pytest.hookimpl(hookwrapper=True)
189
+ def pytest_fixture_setup(self, fixturedef):
190
+ fixture_name = getattr(fixturedef.func, 'test_displayname', fixturedef.argname)
191
+
192
+ container_uuid = self._cache.get(fixturedef)
193
+
194
+ if not container_uuid:
195
+ container_uuid = self._cache.push(fixturedef)
196
+ container = FixturesContainer(uuid=container_uuid)
197
+ self.__fixture_manager.start_group(container_uuid, container)
198
+
199
+ self.__fixture_manager.update_group(container_uuid)
200
+
201
+ before_fixture_uuid = uuid4()
202
+ before_fixture = FixtureResult(title=fixture_name)
203
+
204
+ self.__fixture_manager.start_before_fixture(container_uuid, before_fixture_uuid, before_fixture)
205
+
206
+ outcome = yield
207
+
208
+ results_steps_data = self.__step_manager.get_steps_tree()
209
+
210
+ self.__fixture_manager.stop_before_fixture(before_fixture_uuid,
211
+ outcome=utils.get_outcome_status(outcome), steps=results_steps_data)
212
+
213
+ finalizers = getattr(fixturedef, '_finalizers', [])
214
+ for index, finalizer in enumerate(finalizers):
215
+ finalizer_name = getattr(finalizer, "__name__", index)
216
+ name = f'{fixture_name}::{finalizer_name}'
217
+ finalizers[index] = FixtureContext(finalizer, parent_uuid=container_uuid, name=name)
218
+
219
+ @pytest.hookimpl(hookwrapper=True, trylast=True)
220
+ def pytest_runtest_call(self):
221
+ yield
222
+
223
+ if not self.__executable_test:
224
+ return
225
+
226
+ test_results_steps = self.__step_manager.get_steps_tree()
227
+ self.__executable_test.step_results = test_results_steps
228
+
229
+ @pytest.hookimpl(hookwrapper=True)
230
+ def pytest_fixture_post_finalizer(self, fixturedef):
231
+ if not self.__executable_test:
232
+ return
233
+
234
+ yield
235
+
236
+ if hasattr(fixturedef, 'cached_result') and self._cache.get(fixturedef):
237
+ group_uuid = self._cache.pop(fixturedef)
238
+ self.__fixture_manager.stop_group(group_uuid)
239
+
240
+ @pytest.hookimpl
241
+ def pytest_runtest_logreport(self, report):
242
+ if self.__executable_test:
243
+ if report.when == 'setup':
244
+ self.__executable_test.outcome = report.outcome
245
+ self.__executable_test.status_type = STATUS_TYPE.get(report.outcome, None)
246
+ if report.longreprtext:
247
+ self.__executable_test.message = report.longreprtext
248
+
249
+ if report.when == 'call':
250
+ self.__executable_test.outcome = report.outcome
251
+ self.__executable_test.status_type = STATUS_TYPE.get(report.outcome, None)
252
+
253
+ if report.failed or report.outcome == 'rerun':
254
+ self.__executable_test.outcome = 'failed'
255
+ self.__executable_test.status_type = STATUS_TYPE.get('failed', None)
256
+
257
+ if report.longreprtext:
258
+ self.__executable_test.traces = report.longreprtext
259
+
260
+ if hasattr(report, 'wasxfail') and not report.passed:
261
+ self.__executable_test.outcome = 'xfailed'
262
+ self.__executable_test.status_type = STATUS_TYPE.get('xfailed', None)
263
+
264
+ if report.longreprtext:
265
+ self.__executable_test.traces = report.longreprtext
266
+
267
+ self.__executable_test.duration += report.duration * 1000
268
+
269
+ @pytest.hookimpl
270
+ def pytest_runtest_logfinish(self):
271
+ if not self.__executable_test:
272
+ return
273
+
274
+ self.__adapter_manager.write_test(
275
+ utils.convert_executable_test_to_test_result_model(self.__executable_test))
276
+
277
+ @pytest.hookimpl
278
+ def pytest_sessionfinish(self, session):
279
+ self.__adapter_manager.on_block_completed()
280
+ self.__adapter_manager.write_tests()
281
+
282
+ @adapter.hookimpl
283
+ def add_link(self, link):
284
+ if self.__executable_test:
285
+ self.__executable_test.result_links.append(link)
286
+
287
+ @adapter.hookimpl
288
+ def add_message(self, test_message: str):
289
+ if self.__executable_test:
290
+ self.__executable_test.message = str(test_message)
291
+
292
+ @adapter.hookimpl
293
+ def add_attachments(self, attach_paths: list or tuple):
294
+ if self.__executable_test:
295
+ self.__executable_test.attachments += self.__adapter_manager.load_attachments(attach_paths)
296
+
297
+ @adapter.hookimpl
298
+ def create_attachment(self, body, name: str):
299
+ if self.__executable_test:
300
+ self.__executable_test.attachments += self.__adapter_manager.create_attachment(body, name)
301
+
302
+ @adapter.hookimpl
303
+ def add_work_item_id(self, test_work_item_id: str):
304
+ if self.__executable_test:
305
+ self.__executable_test.work_item_ids.append(test_work_item_id)
306
+
307
+ @adapter.hookimpl
308
+ def add_display_name(self, test_display_name: str):
309
+ if self.__executable_test:
310
+ self.__executable_test.name = test_display_name
311
+
312
+ @adapter.hookimpl
313
+ def add_namespace(self, test_namespace: str):
314
+ if self.__executable_test:
315
+ self.__executable_test.namespace = test_namespace
316
+
317
+ @adapter.hookimpl
318
+ def add_classname(self, test_classname: str):
319
+ if self.__executable_test:
320
+ self.__executable_test.classname = test_classname
321
+
322
+ @adapter.hookimpl
323
+ def add_external_id(self, test_external_id: str):
324
+ if self.__executable_test:
325
+ self.__executable_test.external_id = test_external_id
326
+
327
+ @adapter.hookimpl
328
+ def add_title(self, test_title: str):
329
+ if self.__executable_test:
330
+ self.__executable_test.title = str(test_title)
331
+
332
+ @adapter.hookimpl
333
+ def add_description(self, test_description: str):
334
+ if self.__executable_test:
335
+ self.__executable_test.description = test_description
336
+
337
+ @adapter.hookimpl
338
+ def add_label(self, test_label: str):
339
+ if self.__executable_test:
340
+ self.__executable_test.labels.append({'name': test_label})
341
+
342
+ @adapter.hookimpl
343
+ def add_parameter(self, name: str, value: str):
344
+ if self.__executable_test:
345
+ self.__executable_test.parameters[name] = value
346
+
347
+ @adapter.hookimpl
348
+ def start_fixture(self, parent_uuid, uuid, title):
349
+ after_fixture = FixtureResult(title=title)
350
+ self.__fixture_manager.start_after_fixture(parent_uuid, uuid, after_fixture)
351
+
352
+ @adapter.hookimpl
353
+ def stop_fixture(self, uuid, exc_type, exc_val, exc_tb):
354
+ results_steps_data = self.__step_manager.get_steps_tree()
355
+
356
+ self.__fixture_manager.stop_after_fixture(uuid,
357
+ outcome=utils.get_status(exc_val),
358
+ steps=results_steps_data,
359
+ message=utils.get_message(exc_type, exc_val),
360
+ stacktrace=utils.get_traceback(exc_tb))
361
+
362
+ def _update_fixtures_external_ids(self, item):
363
+ for fixturedef in self._test_fixtures(item):
364
+ group_uuid = self._cache.get(fixturedef)
365
+ if group_uuid:
366
+ group = self.__fixture_manager.get_item(group_uuid)
367
+ else:
368
+ group_uuid = self._cache.push(fixturedef)
369
+ group = FixturesContainer(uuid=group_uuid)
370
+ self.__fixture_manager.start_group(group_uuid, group)
371
+ if self.__executable_test.external_id not in group.external_ids:
372
+ self.__fixture_manager.update_group(group_uuid, external_ids=self.__executable_test.external_id)
373
+
374
+ def _test_fixtures(self, item):
375
+ fixturemanager = item.session._fixturemanager
376
+ fixturedefs = []
377
+
378
+ if hasattr(item, "_request") and hasattr(item._request, "fixturenames"):
379
+ for name in item._request.fixturenames:
380
+ if self.__pytest_info and version.parse(self.__pytest_info["version"]) >= version.parse("8.1.0"):
381
+ fixturedefs_pytest = fixturemanager.getfixturedefs(name, item)
382
+ else:
383
+ fixturedefs_pytest = fixturemanager.getfixturedefs(name, item.nodeid)
384
+
385
+ if fixturedefs_pytest:
386
+ fixturedefs.extend(fixturedefs_pytest)
387
+
388
+ return fixturedefs
File without changes
@@ -0,0 +1,33 @@
1
+ from attr import attrs, attrib
2
+ from attr import Factory
3
+
4
+
5
+ @attrs
6
+ class ExecutableTest:
7
+ external_id = attrib()
8
+ name = attrib()
9
+ steps = attrib(default=Factory(list))
10
+ step_results = attrib(default=Factory(list))
11
+ setup_steps = attrib(default=Factory(list))
12
+ setup_step_results = attrib(default=Factory(list))
13
+ teardown_steps = attrib(default=Factory(list))
14
+ teardown_step_results = attrib(default=Factory(list))
15
+ result_links = attrib(default=Factory(list))
16
+ duration = attrib(default=None)
17
+ outcome = attrib(default=None)
18
+ status_type = attrib(default=None)
19
+ failure_reason_names = attrib(default=Factory(list))
20
+ traces = attrib(default=None)
21
+ attachments = attrib(default=Factory(list))
22
+ parameters = attrib(default=Factory(dict))
23
+ properties = attrib(default=Factory(dict))
24
+ namespace = attrib(default=None)
25
+ classname = attrib(default=None)
26
+ title = attrib(default=None)
27
+ description = attrib(default=None)
28
+ links = attrib(default=Factory(list))
29
+ labels = attrib(default=Factory(list))
30
+ tags = attrib(default=Factory(list))
31
+ work_item_ids = attrib(default=Factory(list))
32
+ message = attrib(default=None)
33
+ node_id = attrib(default=None)
@@ -0,0 +1,223 @@
1
+ import re
2
+ import json
3
+ from urllib.parse import urlparse
4
+ import pytest
5
+
6
+ from testit_adapter_pytest.listener import TmsListener
7
+ from testit_python_commons.services import TmsPluginManager
8
+
9
+
10
+ def _adapter_mode_type(value):
11
+ if value is None:
12
+ raise ValueError("Adapter mode cannot be None! Valid modes: 0, 1, 2")
13
+ valid_modes = ['0', '1', '2']
14
+ if value not in valid_modes:
15
+ raise ValueError(f"Unknown adapter mode '{value}'! Valid modes: {', '.join(valid_modes)}")
16
+ return value
17
+
18
+
19
+ def _boolean_type(value):
20
+ if value is None:
21
+ raise ValueError("Boolean value cannot be None! Must be 'true' or 'false'")
22
+ valid_values = ['true', 'false']
23
+ if value.lower() not in valid_values:
24
+ raise ValueError(f"Invalid value '{value}'! Must be 'true' or 'false'")
25
+ return value.lower()
26
+
27
+
28
+ def _uuid_type(value):
29
+ if value is None:
30
+ raise ValueError("UUID cannot be None!")
31
+ uuid_pattern = re.compile(r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$', re.I)
32
+ if not uuid_pattern.match(value):
33
+ raise ValueError(f"Invalid UUID format: '{value}'!")
34
+ return value
35
+
36
+
37
+ def _url_type(value):
38
+ if value is None:
39
+ raise ValueError("URL cannot be None!")
40
+ if not value.startswith(('http://', 'https://')):
41
+ raise ValueError(f"Invalid URL format: '{value}'!")
42
+ url = urlparse(value)
43
+ if not all([url.scheme, url.netloc]):
44
+ raise ValueError(f"Invalid URL format: '{value}'!")
45
+ return value
46
+
47
+
48
+ def _proxy_type(value):
49
+ if value is None:
50
+ raise ValueError("Proxy cannot be None!")
51
+ try:
52
+ proxy_dict = json.loads(value)
53
+ if not isinstance(proxy_dict, dict):
54
+ raise ValueError(f"Proxy must be a JSON object, got {type(proxy_dict).__name__}")
55
+
56
+ valid_keys = {'http', 'https'}
57
+ for key in proxy_dict.keys():
58
+ if key not in valid_keys:
59
+ raise ValueError(f"Invalid proxy key '{key}'! Must be 'http' or 'https'")
60
+
61
+ for key, url in proxy_dict.items():
62
+ if not isinstance(url, str):
63
+ raise ValueError(f"Proxy URL for '{key}' must be string, got {type(url).__name__}")
64
+ if not url.startswith(('http://', 'https://')):
65
+ raise ValueError(f"Invalid {key} proxy URL: '{url}'! Must start with http:// or https://")
66
+ parsed = urlparse(url)
67
+ if not parsed.netloc:
68
+ raise ValueError(f"Invalid {key} proxy URL: '{url}'! Missing hostname")
69
+
70
+ return value
71
+ except json.JSONDecodeError:
72
+ raise ValueError(f"Invalid JSON format for proxy: '{value}'!")
73
+ except ValueError as e:
74
+ raise ValueError(str(e))
75
+
76
+ def pytest_addoption(parser):
77
+ parser.getgroup('testit').addoption(
78
+ '--testit',
79
+ action='store_true',
80
+ dest="tms_report",
81
+ help='Pytest plugin for Test IT'
82
+ )
83
+ parser.getgroup('testit').addoption(
84
+ '--tmsUrl',
85
+ action="store",
86
+ dest="set_url",
87
+ type=_url_type,
88
+ metavar="https://demo.testit.software",
89
+ help='Set location of the TMS instance'
90
+ )
91
+ parser.getgroup('testit').addoption(
92
+ '--tmsPrivateToken',
93
+ action="store",
94
+ dest="set_private_token",
95
+ metavar="T2lKd2pLZGI4WHRhaVZUejNl",
96
+ help='Set API secret key'
97
+ )
98
+ parser.getgroup('testit').addoption(
99
+ '--tmsProjectId',
100
+ action="store",
101
+ dest="set_project_id",
102
+ type=_uuid_type,
103
+ metavar="15dbb164-c1aa-4cbf-830c-8c01ae14f4fb",
104
+ help='Set project ID'
105
+ )
106
+ parser.getgroup('testit').addoption(
107
+ '--tmsConfigurationId',
108
+ action="store",
109
+ dest="set_configuration_id",
110
+ type=_uuid_type,
111
+ metavar="d354bdac-75dc-4e3d-84d4-71186c0dddfc",
112
+ help='Set configuration ID'
113
+ )
114
+ parser.getgroup('testit').addoption(
115
+ '--tmsTestRunId',
116
+ action="store",
117
+ dest="set_test_run_id",
118
+ type=_uuid_type,
119
+ metavar="5236eb3f-7c05-46f9-a609-dc0278896464",
120
+ help='Set test run ID (optional)'
121
+ )
122
+ parser.getgroup('debug').addoption(
123
+ '--tmsProxy',
124
+ action="store",
125
+ dest="set_tms_proxy",
126
+ type=_proxy_type,
127
+ metavar='{"http":"http://localhost:8888","https":"http://localhost:8888"}',
128
+ help='Set proxy for sending requests (optional)'
129
+ )
130
+ parser.getgroup('testit').addoption(
131
+ '--tmsTestRunName',
132
+ action="store",
133
+ dest="set_test_run_name",
134
+ metavar="Custom name of test run",
135
+ help='Set custom name of test run (optional)'
136
+ )
137
+ parser.getgroup('testit').addoption(
138
+ '--tmsAdapterMode',
139
+ action="store",
140
+ type=_adapter_mode_type,
141
+ dest="set_adapter_mode",
142
+ metavar="1",
143
+ help="""
144
+ Set adapter mode with test run (optional):
145
+ 0 - with filtering autotests by launch\'s suite in TMS (Default)
146
+ 1 - without filtering autotests by launch\'s suite in TMS
147
+ 2 - create new test run in TMS
148
+ """
149
+ )
150
+ parser.getgroup('testit').addoption(
151
+ '--tmsConfigFile',
152
+ action="store",
153
+ dest="set_config_file",
154
+ metavar="tmsConfigFile",
155
+ help='Set custom name of configuration file'
156
+ )
157
+ parser.getgroup('testit').addoption(
158
+ '--tmsCertValidation',
159
+ action="store",
160
+ dest="set_cert_validation",
161
+ type=_boolean_type,
162
+ metavar="false",
163
+ help='Set certificate validation (true/false)'
164
+ )
165
+ parser.getgroup('testit').addoption(
166
+ '--tmsAutomaticCreationTestCases',
167
+ action="store",
168
+ dest="set_automatic_creation_test_cases",
169
+ type=_boolean_type,
170
+ metavar="false",
171
+ help="""
172
+ Set mode of automatic creation test cases (optional):
173
+ true - create a test case linked to the created autotest (not to the updated autotest)
174
+ false - not create a test case (Default)
175
+ """
176
+ )
177
+ parser.getgroup('testit').addoption(
178
+ '--tmsAutomaticUpdationLinksToTestCases',
179
+ action="store",
180
+ dest="set_automatic_updation_links_to_test_cases",
181
+ type=_boolean_type,
182
+ metavar="false",
183
+ help="""
184
+ Set mode of automatic updation links to test cases (optional):
185
+ true - update links to test cases
186
+ false - not update links to test cases (Default)
187
+ """
188
+ )
189
+ parser.getgroup('testit').addoption(
190
+ '--tmsImportRealtime',
191
+ action="store",
192
+ dest="set_import_realtime",
193
+ type=_boolean_type,
194
+ metavar="false",
195
+ help="""
196
+ Set mode of import type selection when launching autotests (optional):
197
+ true - the adapter will create/update each autotest in real time (Default)
198
+ false - the adapter will create/update multiple autotests
199
+ """
200
+ )
201
+
202
+
203
+ @pytest.hookimpl(tryfirst=True)
204
+ def pytest_load_initial_conftests(early_config, parser, args):
205
+ ns = getattr(early_config, "known_args_namespace", None)
206
+ if ns is not None and hasattr(ns, "tms_report"):
207
+ TmsPluginManager.set_pytest_tms_report(ns.tms_report)
208
+
209
+
210
+ def pytest_unconfigure(config):
211
+ TmsPluginManager.set_pytest_tms_report(None)
212
+
213
+
214
+ @pytest.hookimpl(tryfirst=True)
215
+ def pytest_cmdline_main(config):
216
+ if config.option.tms_report:
217
+ listener = TmsListener(
218
+ TmsPluginManager.get_adapter_manager(config.option),
219
+ TmsPluginManager.get_step_manager(),
220
+ TmsPluginManager.get_fixture_manager())
221
+
222
+ config.pluginmanager.register(listener)
223
+ TmsPluginManager.get_plugin_manager().register(listener)