testit-cli 2.1.0__tar.gz → 2.1.2__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.
- {testit_cli-2.1.0 → testit_cli-2.1.2}/PKG-INFO +12 -3
- {testit_cli-2.1.0 → testit_cli-2.1.2}/setup.py +2 -2
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/apiclient.py +25 -12
- testit_cli-2.1.2/src/testit_cli/autotests_filter.py +29 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/click_commands.py +29 -5
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/converter.py +65 -18
- testit_cli-2.1.2/src/testit_cli/filter_factory.py +121 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/importer.py +3 -3
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/models/config.py +1 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/models/testcase.py +1 -1
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/service.py +15 -4
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/service_factory.py +5 -3
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli.egg-info/PKG-INFO +12 -3
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli.egg-info/SOURCES.txt +2 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli.egg-info/requires.txt +1 -1
- {testit_cli-2.1.0 → testit_cli-2.1.2}/tests/test_click.py +1 -1
- {testit_cli-2.1.0 → testit_cli-2.1.2}/LICENSE +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/README.md +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/setup.cfg +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/__init__.py +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/__main__.py +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/dir_worker.py +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/file_worker.py +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/logger.py +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/models/__init__.py +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/models/mode.py +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/models/status.py +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/models/testrun.py +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/parser.py +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli/validation.py +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli.egg-info/dependency_links.txt +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli.egg-info/entry_points.txt +0 -0
- {testit_cli-2.1.0 → testit_cli-2.1.2}/src/testit_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: testit-cli
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: This tool is the command line wrapper of Test IT allowing you to upload the test results in real time to Test IT
|
|
5
5
|
Home-page: https://pypi.org/project/testit-cli/
|
|
6
6
|
Author: Integration team
|
|
@@ -16,10 +16,19 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: testit-api-client==
|
|
19
|
+
Requires-Dist: testit-api-client==5.0.0
|
|
20
20
|
Requires-Dist: validators
|
|
21
21
|
Requires-Dist: tqdm
|
|
22
22
|
Requires-Dist: click~=8.0.4
|
|
23
|
+
Dynamic: author
|
|
24
|
+
Dynamic: author-email
|
|
25
|
+
Dynamic: classifier
|
|
26
|
+
Dynamic: description
|
|
27
|
+
Dynamic: description-content-type
|
|
28
|
+
Dynamic: home-page
|
|
29
|
+
Dynamic: license
|
|
30
|
+
Dynamic: requires-dist
|
|
31
|
+
Dynamic: summary
|
|
23
32
|
|
|
24
33
|
# Test IT CLI
|
|
25
34
|
|
|
@@ -2,7 +2,7 @@ from setuptools import find_packages, setup
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name='testit-cli',
|
|
5
|
-
version='2.1.
|
|
5
|
+
version='2.1.2',
|
|
6
6
|
description='This tool is the command line wrapper of Test IT allowing you to upload the test results in real time '
|
|
7
7
|
'to Test IT',
|
|
8
8
|
long_description=open('README.md', "r").read(),
|
|
@@ -24,7 +24,7 @@ setup(
|
|
|
24
24
|
py_modules=['testit_cli'],
|
|
25
25
|
packages=find_packages(where='src'),
|
|
26
26
|
package_dir={'': 'src'},
|
|
27
|
-
install_requires=['testit-api-client==
|
|
27
|
+
install_requires=['testit-api-client==5.0.0', 'validators', 'tqdm', 'click~=8.0.4'],
|
|
28
28
|
entry_points={
|
|
29
29
|
'console_scripts': [
|
|
30
30
|
'testit = testit_cli.__main__:console_main'
|
|
@@ -5,7 +5,7 @@ import typing
|
|
|
5
5
|
|
|
6
6
|
from testit_api_client import ApiClient as TmsClient
|
|
7
7
|
from testit_api_client import Configuration
|
|
8
|
-
from testit_api_client.
|
|
8
|
+
from testit_api_client.api import AttachmentsApi, AutoTestsApi, TestRunsApi, TestResultsApi
|
|
9
9
|
from testit_api_client.models import AttachmentPutModel, TestRunV2PostShortModel
|
|
10
10
|
|
|
11
11
|
from .converter import Converter
|
|
@@ -28,6 +28,7 @@ class ApiClient:
|
|
|
28
28
|
self.__test_run_api = TestRunsApi(api_client=client)
|
|
29
29
|
self.__autotest_api = AutoTestsApi(api_client=client)
|
|
30
30
|
self.__attachments_api = AttachmentsApi(api_client=client)
|
|
31
|
+
self.__test_results_api = TestResultsApi(api_client=client)
|
|
31
32
|
|
|
32
33
|
def create_test_run(self, project_id: str, name: str) -> TestRun:
|
|
33
34
|
"""Function creates test run and returns test run id."""
|
|
@@ -36,7 +37,7 @@ class ApiClient:
|
|
|
36
37
|
|
|
37
38
|
test_run = self.__test_run_api.create_empty(test_run_v2_post_short_model=model)
|
|
38
39
|
|
|
39
|
-
logging.info(f'Created new testrun (ID: {test_run
|
|
40
|
+
logging.info(f'Created new testrun (ID: {test_run.id})')
|
|
40
41
|
logging.debug(f"Test run created: {test_run}")
|
|
41
42
|
|
|
42
43
|
return Converter.test_run_v2_get_model_to_test_run(test_run)
|
|
@@ -46,10 +47,9 @@ class ApiClient:
|
|
|
46
47
|
model = Converter.test_run_to_update_empty_request(test_run)
|
|
47
48
|
logging.debug(f"Updating test run with model: {model}")
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
self.__test_run_api.update_empty(test_run_v2_put_model=model)
|
|
50
51
|
|
|
51
52
|
logging.info(f'Updated testrun (ID: {test_run.id})')
|
|
52
|
-
logging.debug(f"Test run updated: {response}")
|
|
53
53
|
|
|
54
54
|
def complete_test_run(self, test_run_id: str):
|
|
55
55
|
"""Function completes test run."""
|
|
@@ -72,15 +72,15 @@ class ApiClient:
|
|
|
72
72
|
|
|
73
73
|
logging.error(f"Test run {test_run_id} not found!")
|
|
74
74
|
|
|
75
|
-
def
|
|
76
|
-
"""Function returns
|
|
77
|
-
logging.debug(f"Getting
|
|
75
|
+
def get_autotests(self, model: Converter.project_id_and_external_id_to_autotests_search_post_request):
|
|
76
|
+
"""Function returns list of AutoTestModel."""
|
|
77
|
+
logging.debug(f"Getting autotests: {model}")
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
autotests = self.__autotest_api.api_v2_auto_tests_search_post(autotests_select_model=model)
|
|
80
80
|
|
|
81
|
-
logging.debug(f"Got
|
|
81
|
+
logging.debug(f"Got autotests: {autotests}")
|
|
82
82
|
|
|
83
|
-
return
|
|
83
|
+
return autotests
|
|
84
84
|
|
|
85
85
|
def create_autotest(self, model: Converter.test_result_to_create_autotest_request):
|
|
86
86
|
"""Function creates autotest and returns autotest id."""
|
|
@@ -90,7 +90,7 @@ class ApiClient:
|
|
|
90
90
|
|
|
91
91
|
logging.debug(f"Created autotest {response}")
|
|
92
92
|
|
|
93
|
-
return response
|
|
93
|
+
return response.id
|
|
94
94
|
|
|
95
95
|
def update_autotest(self, model: Converter.test_result_to_update_autotest_request):
|
|
96
96
|
"""Function updates autotest"""
|
|
@@ -128,7 +128,7 @@ class ApiClient:
|
|
|
128
128
|
try:
|
|
129
129
|
attachment_response = self.__attachments_api.api_v2_attachments_post(file=open(attachment, "rb"))
|
|
130
130
|
|
|
131
|
-
attachment_ids.append(AttachmentPutModel(attachment_response
|
|
131
|
+
attachment_ids.append(AttachmentPutModel(id=attachment_response.id))
|
|
132
132
|
|
|
133
133
|
logging.debug(f'Attachment "{attachment}" was uploaded')
|
|
134
134
|
except Exception as exc:
|
|
@@ -137,3 +137,16 @@ class ApiClient:
|
|
|
137
137
|
logging.error(f'File "{attachment}" was not found!')
|
|
138
138
|
|
|
139
139
|
return attachment_ids
|
|
140
|
+
|
|
141
|
+
def get_test_results(
|
|
142
|
+
self,
|
|
143
|
+
model: Converter.testrun_id_and_configuration_id_and_in_progress_outcome_to_test_results_search_post_request):
|
|
144
|
+
"""Function returns list of TestResultShortGetModel."""
|
|
145
|
+
logging.debug(f"Getting test results: {model}")
|
|
146
|
+
|
|
147
|
+
test_results = self.__test_results_api.api_v2_test_results_search_post(
|
|
148
|
+
test_results_filter_request=model)
|
|
149
|
+
|
|
150
|
+
logging.debug(f"Got test results: {test_results}")
|
|
151
|
+
|
|
152
|
+
return test_results
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
|
|
3
|
+
from .apiclient import ApiClient
|
|
4
|
+
from .converter import Converter
|
|
5
|
+
from .filter_factory import FilterFactory
|
|
6
|
+
from .models.config import Config
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AutotestsFilter:
|
|
10
|
+
def __init__(self, api_client: ApiClient, config: Config):
|
|
11
|
+
self.__api_client = api_client
|
|
12
|
+
self.__config = config
|
|
13
|
+
|
|
14
|
+
def create_filter(self):
|
|
15
|
+
"""Function returns str of filter by autotests for test Framework run command."""
|
|
16
|
+
test_results_search_post_model = Converter.testrun_id_and_configuration_id_and_in_progress_outcome_to_test_results_search_post_request(
|
|
17
|
+
self.__config.testrun_id,
|
|
18
|
+
self.__config.configuration_id)
|
|
19
|
+
test_results = self.__api_client.get_test_results(test_results_search_post_model)
|
|
20
|
+
autotest_ids = Converter.test_result_short_get_models_to_autotest_ids(test_results)
|
|
21
|
+
autotests_search_post_model = Converter.autotest_ids_to_autotests_search_post_request(autotest_ids)
|
|
22
|
+
autotests = self.__api_client.get_autotests(autotests_search_post_model)
|
|
23
|
+
external_keys = Converter.autotest_models_to_external_keys(autotests)
|
|
24
|
+
|
|
25
|
+
return FilterFactory.get(self.__config, external_keys)
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def __get_external_id(value: str):
|
|
29
|
+
return hashlib.md5(value.encode("utf-8")).hexdigest()
|
|
@@ -75,7 +75,7 @@ class ExtraArgsForOption(click.Option):
|
|
|
75
75
|
@click.option("-dcv", "--disable-cert-validation", is_flag=True, help="Disables certificate validation")
|
|
76
76
|
def upload_results(url, token, configuration_id, testrun_id, separator, namespace, classname, results, debug, attachments, disable_cert_validation):
|
|
77
77
|
"""Uploading results from different streams"""
|
|
78
|
-
config = Config(url, token, "", configuration_id, testrun_id, "", separator, namespace, classname, list(chain.from_iterable(results)), debug, "", list(chain.from_iterable(attachments)), disable_cert_validation)
|
|
78
|
+
config = Config(url, token, "", configuration_id, testrun_id, "", separator, namespace, classname, list(chain.from_iterable(results)), debug, "", list(chain.from_iterable(attachments)), disable_cert_validation, "")
|
|
79
79
|
service = ServiceFactory().get(config)
|
|
80
80
|
|
|
81
81
|
service.upload_results()
|
|
@@ -100,7 +100,7 @@ def import_results(url, token, project_id, configuration_id, testrun_id, testrun
|
|
|
100
100
|
if testrun_id is not None and testrun_name is not None:
|
|
101
101
|
click.echo("Illegal usage: `{}` are mutually exclusive arguments.".format(', '.join(["--testrun-id", "--testrun-name"])), err=True)
|
|
102
102
|
|
|
103
|
-
config = Config(url, token, project_id, configuration_id, testrun_id, testrun_name, separator, namespace, classname, list(chain.from_iterable(results)), debug, "", list(chain.from_iterable(attachments)), disable_cert_validation)
|
|
103
|
+
config = Config(url, token, project_id, configuration_id, testrun_id, testrun_name, separator, namespace, classname, list(chain.from_iterable(results)), debug, "", list(chain.from_iterable(attachments)), disable_cert_validation, "")
|
|
104
104
|
service = ServiceFactory().get(config)
|
|
105
105
|
|
|
106
106
|
service.import_results()
|
|
@@ -123,7 +123,7 @@ def testrun():
|
|
|
123
123
|
@click.option("-dcv", "--disable-cert-validation", is_flag=True, help="Disables certificate validation")
|
|
124
124
|
def create_test_run(url, token, project_id, testrun_name, output, debug, attachments, disable_cert_validation):
|
|
125
125
|
"""Creating a new test run"""
|
|
126
|
-
config = Config(url, token, project_id, "", "", testrun_name, "", "", "", [], debug, output, list(chain.from_iterable(attachments)), disable_cert_validation)
|
|
126
|
+
config = Config(url, token, project_id, "", "", testrun_name, "", "", "", [], debug, output, list(chain.from_iterable(attachments)), disable_cert_validation, "")
|
|
127
127
|
service = ServiceFactory().get(config)
|
|
128
128
|
|
|
129
129
|
service.create_test_run()
|
|
@@ -138,7 +138,7 @@ def create_test_run(url, token, project_id, testrun_name, output, debug, attachm
|
|
|
138
138
|
@click.option("-dcv", "--disable-cert-validation", is_flag=True, help="Disables certificate validation")
|
|
139
139
|
def complete_test_run(url, token, testrun_id, debug, attachments, disable_cert_validation):
|
|
140
140
|
"""Completing the test run"""
|
|
141
|
-
config = Config(url, token, "", "", testrun_id, "", "", "", "", [], debug, "", list(chain.from_iterable(attachments)), disable_cert_validation)
|
|
141
|
+
config = Config(url, token, "", "", testrun_id, "", "", "", "", [], debug, "", list(chain.from_iterable(attachments)), disable_cert_validation, "")
|
|
142
142
|
service = ServiceFactory().get(config)
|
|
143
143
|
|
|
144
144
|
service.finished_test_run()
|
|
@@ -153,7 +153,31 @@ def complete_test_run(url, token, testrun_id, debug, attachments, disable_cert_v
|
|
|
153
153
|
@click.option("-dcv", "--disable-cert-validation", is_flag=True, help="Disables certificate validation")
|
|
154
154
|
def upload_attachments_for_test_run(url, token, testrun_id, debug, attachments, disable_cert_validation):
|
|
155
155
|
"""Uploading attachments for the test run"""
|
|
156
|
-
config = Config(url, token, "", "", testrun_id, "", "", "", "", [], debug, "", list(chain.from_iterable(attachments)), disable_cert_validation)
|
|
156
|
+
config = Config(url, token, "", "", testrun_id, "", "", "", "", [], debug, "", list(chain.from_iterable(attachments)), disable_cert_validation, "")
|
|
157
157
|
service = ServiceFactory().get(config)
|
|
158
158
|
|
|
159
159
|
service.upload_attachments_for_test_run()
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
PYTHON_FRAMEWORKS = ['pytest', 'robotframework', 'behave', 'nose']
|
|
163
|
+
JAVA_FRAMEWORKS = ['gradle-testng', 'gradle-junit5', 'gradle-junit4', 'gradle-cucumber', 'maven-testng', 'maven-junit5', 'maven-junit4', 'maven-cucumber']
|
|
164
|
+
JAVASCRIPT_FRAMEWORKS = ['cucumberjs', 'codeceptjs', 'jest', 'mocha', 'playwright', 'testcafe']
|
|
165
|
+
DOTNET_FRAMEWORKS = ['mstest', 'nunit', 'xunit', 'specflow']
|
|
166
|
+
GOLANG_FRAMEWORKS = ['golang']
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
@execute.command("autotests_filter")
|
|
170
|
+
@click.option("-u", "--url", type=str, envvar='TMS_URL', required=True, help="Set url address of the Test IT instance (https://demo.testit.software)", callback=validate_url)
|
|
171
|
+
@click.option("-t", "--token", type=str, envvar='TMS_TOKEN', required=True, help="Set API token (T2lKd2pLZGI4WHRhaVZUejNl)")
|
|
172
|
+
@click.option("-ci", "--configuration-id", type=str, envvar='TMS_CONFIGURATION_ID', required=True, help="Set configuration id (15dbb164-c1aa-4cbf-830c-8c01ae14f4fb)", callback=validate_uuid)
|
|
173
|
+
@click.option("-ti", "--testrun-id", type=str, envvar='TMS_TEST_RUN_ID', required=True, help="Set test run id (3802f329-190c-4617-8bb0-2c3696abeb8f)", callback=validate_uuid)
|
|
174
|
+
@click.option("-f", "--framework", type=click.Choice(PYTHON_FRAMEWORKS + JAVA_FRAMEWORKS + JAVASCRIPT_FRAMEWORKS + DOTNET_FRAMEWORKS + GOLANG_FRAMEWORKS), required=True, help="Set test framework")
|
|
175
|
+
@click.option("-d", "--debug", is_flag=True, help="Set debug logs")
|
|
176
|
+
@click.option("-o", "--output", type=str, required=True, help="Set file path for output (FILE)")
|
|
177
|
+
@click.option("-dcv", "--disable-cert-validation", is_flag=True, help="Disables certificate validation")
|
|
178
|
+
def create_filter_for_framework(url, token, configuration_id, testrun_id, framework, debug, output, disable_cert_validation):
|
|
179
|
+
"""Creating filter by autotests for test frameworks"""
|
|
180
|
+
config = Config(url, token, "", configuration_id, testrun_id, "", "", "", "", [], debug, output, [], disable_cert_validation, framework)
|
|
181
|
+
service = ServiceFactory().get(config)
|
|
182
|
+
|
|
183
|
+
service.create_filter_for_test_framework()
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
|
|
3
3
|
from testit_api_client.models import (
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
AutotestFilterModel,
|
|
5
|
+
SearchAutoTestsQueryIncludesModel,
|
|
6
6
|
AutoTestResultsForTestRunModel,
|
|
7
|
-
|
|
7
|
+
AutotestsSelectModel,
|
|
8
8
|
AttachmentModel,
|
|
9
9
|
AttachmentPutModel,
|
|
10
10
|
AutoTestPostModel,
|
|
@@ -12,7 +12,11 @@ from testit_api_client.models import (
|
|
|
12
12
|
LinkModel,
|
|
13
13
|
LinkPutModel,
|
|
14
14
|
TestRunV2GetModel,
|
|
15
|
-
TestRunV2PutModel
|
|
15
|
+
TestRunV2PutModel,
|
|
16
|
+
TestResultsFilterRequest,
|
|
17
|
+
TestResultOutcome,
|
|
18
|
+
TestResultShortResponse,
|
|
19
|
+
AutoTestModel
|
|
16
20
|
)
|
|
17
21
|
|
|
18
22
|
from .models.testrun import TestRun
|
|
@@ -21,16 +25,59 @@ from .models.testrun import TestRun
|
|
|
21
25
|
class Converter:
|
|
22
26
|
@staticmethod
|
|
23
27
|
def project_id_and_external_id_to_autotests_search_post_request(project_id: str, external_id: str):
|
|
24
|
-
autotests_filter =
|
|
28
|
+
autotests_filter = AutotestFilterModel(
|
|
25
29
|
project_ids=[project_id],
|
|
26
30
|
external_ids=[external_id],
|
|
27
31
|
is_deleted=False)
|
|
28
|
-
autotests_includes =
|
|
32
|
+
autotests_includes = SearchAutoTestsQueryIncludesModel(
|
|
29
33
|
include_steps=False,
|
|
30
34
|
include_links=False,
|
|
31
35
|
include_labels=False)
|
|
32
36
|
|
|
33
|
-
return
|
|
37
|
+
return AutotestsSelectModel(filter=autotests_filter, includes=autotests_includes)
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def autotest_ids_to_autotests_search_post_request(autotest_ids: typing.List[int]):
|
|
41
|
+
autotests_filter = AutotestFilterModel(
|
|
42
|
+
global_ids=autotest_ids)
|
|
43
|
+
autotests_includes = SearchAutoTestsQueryIncludesModel(
|
|
44
|
+
include_steps=False,
|
|
45
|
+
include_links=False,
|
|
46
|
+
include_labels=False)
|
|
47
|
+
|
|
48
|
+
return AutotestsSelectModel(filter=autotests_filter, includes=autotests_includes)
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def testrun_id_and_configuration_id_and_in_progress_outcome_to_test_results_search_post_request(
|
|
52
|
+
testrun_id: str,
|
|
53
|
+
configuration_id: str):
|
|
54
|
+
return TestResultsFilterRequest(
|
|
55
|
+
test_run_ids=[testrun_id],
|
|
56
|
+
configuration_ids=[configuration_id],
|
|
57
|
+
outcomes=[TestResultOutcome("InProgress")])
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def test_result_short_get_models_to_autotest_ids(test_results: typing.List[TestResultShortResponse]):
|
|
61
|
+
autotest_ids = []
|
|
62
|
+
|
|
63
|
+
for test_result in test_results:
|
|
64
|
+
autotest_ids.append(test_result.autotest_global_id)
|
|
65
|
+
|
|
66
|
+
return autotest_ids
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def autotest_models_to_external_keys(autotests: typing.List[AutoTestModel]):
|
|
70
|
+
external_keys = []
|
|
71
|
+
|
|
72
|
+
for autotest in autotests:
|
|
73
|
+
external_key = autotest.external_key
|
|
74
|
+
|
|
75
|
+
if external_key is None:
|
|
76
|
+
continue
|
|
77
|
+
|
|
78
|
+
external_keys.append(external_key)
|
|
79
|
+
|
|
80
|
+
return external_keys
|
|
34
81
|
|
|
35
82
|
@staticmethod
|
|
36
83
|
def test_result_to_create_autotest_request(result, external_id: str, project_id: str):
|
|
@@ -58,9 +105,9 @@ class Converter:
|
|
|
58
105
|
result, external_id: str, configuration_id: str
|
|
59
106
|
):
|
|
60
107
|
return AutoTestResultsForTestRunModel(
|
|
61
|
-
configuration_id,
|
|
62
|
-
external_id,
|
|
63
|
-
result.get_status(),
|
|
108
|
+
configuration_id=configuration_id,
|
|
109
|
+
auto_test_external_id=external_id,
|
|
110
|
+
outcome=result.get_status(),
|
|
64
111
|
traces=result.get_trace(),
|
|
65
112
|
duration=round(result.get_duration()),
|
|
66
113
|
message=result.get_message(),
|
|
@@ -69,14 +116,14 @@ class Converter:
|
|
|
69
116
|
@classmethod
|
|
70
117
|
def test_run_v2_get_model_to_test_run(cls, test_run_model: TestRunV2GetModel) -> TestRun:
|
|
71
118
|
return TestRun(
|
|
72
|
-
id=test_run_model
|
|
73
|
-
project_id=test_run_model
|
|
74
|
-
state=test_run_model
|
|
75
|
-
name=test_run_model
|
|
76
|
-
description=test_run_model
|
|
77
|
-
launch_source=test_run_model
|
|
78
|
-
attachments=cls.attachment_models_to_attachment_put_models(test_run_model
|
|
79
|
-
links=cls.link_models_to_link_put_models(test_run_model
|
|
119
|
+
id=test_run_model.id,
|
|
120
|
+
project_id=test_run_model.project_id,
|
|
121
|
+
state=test_run_model.state_name.value,
|
|
122
|
+
name=test_run_model.name,
|
|
123
|
+
description=test_run_model.description,
|
|
124
|
+
launch_source=test_run_model.launch_source,
|
|
125
|
+
attachments=cls.attachment_models_to_attachment_put_models(test_run_model.attachments),
|
|
126
|
+
links=cls.link_models_to_link_put_models(test_run_model.links)
|
|
80
127
|
)
|
|
81
128
|
|
|
82
129
|
@classmethod
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from .models.config import Config
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FilterFactory:
|
|
7
|
+
@classmethod
|
|
8
|
+
def get(cls, config: Config, external_keys: typing.List[str]) -> str:
|
|
9
|
+
initialization = {
|
|
10
|
+
'pytest': cls.__initialize_pytest_filter,
|
|
11
|
+
'robotframework': cls.__initialize_robotframework_filter,
|
|
12
|
+
'behave': cls.__initialize_behave_filter,
|
|
13
|
+
'nose': cls.__initialize_nose_filter,
|
|
14
|
+
'gradle-testng': cls.__initialize_gradle_testng_junit4_junit5_filter,
|
|
15
|
+
'gradle-junit4': cls.__initialize_gradle_testng_junit4_junit5_filter,
|
|
16
|
+
'gradle-junit5': cls.__initialize_gradle_testng_junit4_junit5_filter,
|
|
17
|
+
# 'gradle-jbehave': cls.__initialize_jbehave_filter,
|
|
18
|
+
'gradle-cucumber': cls.__initialize_cucumber_cucumberjs_jest_golang_filter,
|
|
19
|
+
'maven-testng': cls.__initialize_maven_testng_junit4_junit5_filter,
|
|
20
|
+
'maven-junit4': cls.__initialize_maven_testng_junit4_junit5_filter,
|
|
21
|
+
'maven-junit5': cls.__initialize_maven_testng_junit4_junit5_filter,
|
|
22
|
+
# 'maven-jbehave': cls.__initialize_jbehave_filter,
|
|
23
|
+
'maven-cucumber': cls.__initialize_cucumber_cucumberjs_jest_golang_filter,
|
|
24
|
+
'cucumberjs': cls.__initialize_cucumber_cucumberjs_jest_golang_filter,
|
|
25
|
+
'codeceptjs': cls.__initialize_codeceptjs_mocha_playwright_filter,
|
|
26
|
+
'jest': cls.__initialize_cucumber_cucumberjs_jest_golang_filter,
|
|
27
|
+
'mocha': cls.__initialize_codeceptjs_mocha_playwright_filter,
|
|
28
|
+
'playwright': cls.__initialize_codeceptjs_mocha_playwright_filter,
|
|
29
|
+
'mstest': cls.__initialize_mstest_nunit_xunit_filter,
|
|
30
|
+
'nunit': cls.__initialize_mstest_nunit_xunit_filter,
|
|
31
|
+
'xunit': cls.__initialize_mstest_nunit_xunit_filter,
|
|
32
|
+
'specflow': cls.__initialize_specflow_filter,
|
|
33
|
+
'golang': cls.__initialize_cucumber_cucumberjs_jest_golang_filter,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return initialization[config.framework](external_keys)
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def __initialize_pytest_filter(cls, external_keys: typing.List[str]):
|
|
40
|
+
"""Initialize filter for pytest run"""
|
|
41
|
+
return '-k\n' + ' or '.join(external_keys)
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def __initialize_robotframework_filter(external_keys: typing.List[str]):
|
|
45
|
+
"""Initialize filter for RobotFramework run"""
|
|
46
|
+
robotframework_filter = ""
|
|
47
|
+
|
|
48
|
+
for external_key in external_keys:
|
|
49
|
+
robotframework_filter += '-t' + external_key.replace(" ", "") + '\n'
|
|
50
|
+
|
|
51
|
+
return robotframework_filter
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def __initialize_behave_filter(external_keys: typing.List[str]):
|
|
55
|
+
"""Initialize filter for Behave run"""
|
|
56
|
+
return '-n' + '|'.join(external_keys)
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def __initialize_nose_filter(cls, external_keys: typing.List[str]):
|
|
60
|
+
"""Initialize filter for Nose run"""
|
|
61
|
+
return ' '.join(external_keys)
|
|
62
|
+
|
|
63
|
+
@staticmethod
|
|
64
|
+
def __initialize_gradle_testng_junit4_junit5_filter(external_keys: typing.List[str]):
|
|
65
|
+
"""Initialize filter for gradle TestNG or JUnit4 or JUnit5 run with gradle"""
|
|
66
|
+
autotest_keys = []
|
|
67
|
+
|
|
68
|
+
for external_key in external_keys:
|
|
69
|
+
autotest_keys.append('--tests ' + external_key)
|
|
70
|
+
|
|
71
|
+
return ' '.join(autotest_keys)
|
|
72
|
+
|
|
73
|
+
# @classmethod
|
|
74
|
+
# def __initialize_jbehave_filter(cls, external_keys: typing.List[str]):
|
|
75
|
+
# """Initialize filter for JBehave run"""
|
|
76
|
+
# return '+' + ' '.join(external_keys)
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def __initialize_maven_testng_junit4_junit5_filter(external_keys: typing.List[str]):
|
|
80
|
+
"""Initialize filter for TestNG or JUnit4 or JUnit5 run with maven"""
|
|
81
|
+
autotest_keys = []
|
|
82
|
+
|
|
83
|
+
for external_key in external_keys:
|
|
84
|
+
autotest_keys.append('-Dtest=' + external_key)
|
|
85
|
+
|
|
86
|
+
return ' '.join(autotest_keys)
|
|
87
|
+
|
|
88
|
+
@classmethod
|
|
89
|
+
def __initialize_codeceptjs_mocha_playwright_filter(cls, external_keys: typing.List[str]):
|
|
90
|
+
"""Initialize filter for CodeceptJS or Mocha or Playwright run"""
|
|
91
|
+
return '|'.join(external_keys)
|
|
92
|
+
|
|
93
|
+
@classmethod
|
|
94
|
+
def __initialize_cucumber_cucumberjs_jest_golang_filter(cls, external_keys: typing.List[str]):
|
|
95
|
+
"""Initialize filter for Cucumber or CucumberJS or Jest or Golang run"""
|
|
96
|
+
autotest_keys = []
|
|
97
|
+
|
|
98
|
+
for external_key in external_keys:
|
|
99
|
+
autotest_keys.append('^' + external_key + '$')
|
|
100
|
+
|
|
101
|
+
return '|'.join(autotest_keys)
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def __initialize_mstest_nunit_xunit_filter(external_keys: typing.List[str]):
|
|
105
|
+
"""Initialize filter for MSTest or NUnit or XUnit run"""
|
|
106
|
+
autotest_keys = []
|
|
107
|
+
|
|
108
|
+
for external_key in external_keys:
|
|
109
|
+
autotest_keys.append('FullyQualifiedName=' + external_key)
|
|
110
|
+
|
|
111
|
+
return '|'.join(autotest_keys)
|
|
112
|
+
|
|
113
|
+
@staticmethod
|
|
114
|
+
def __initialize_specflow_filter(external_keys: typing.List[str]):
|
|
115
|
+
"""Initialize filter for SpecFlow run"""
|
|
116
|
+
autotest_keys = []
|
|
117
|
+
|
|
118
|
+
for external_key in external_keys:
|
|
119
|
+
autotest_keys.append('FullyQualifiedName~' + external_key)
|
|
120
|
+
|
|
121
|
+
return '|'.join(autotest_keys)
|
|
@@ -21,20 +21,20 @@ class Importer:
|
|
|
21
21
|
+ result.get_name()
|
|
22
22
|
)
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
autotests = self.__api_client.get_autotests(
|
|
25
25
|
Converter.project_id_and_external_id_to_autotests_search_post_request(
|
|
26
26
|
self.__config.project_id, external_id
|
|
27
27
|
)
|
|
28
28
|
)
|
|
29
29
|
|
|
30
|
-
if not
|
|
30
|
+
if not autotests:
|
|
31
31
|
self.__api_client.create_autotest(
|
|
32
32
|
Converter.test_result_to_create_autotest_request(
|
|
33
33
|
result, external_id, self.__config.project_id
|
|
34
34
|
)
|
|
35
35
|
)
|
|
36
36
|
else:
|
|
37
|
-
result.set_is_flaky(
|
|
37
|
+
result.set_is_flaky(autotests[0]['is_flaky'])
|
|
38
38
|
|
|
39
39
|
self.__api_client.update_autotest(
|
|
40
40
|
Converter.test_result_to_update_autotest_request(
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
|
+
from .autotests_filter import AutotestsFilter
|
|
3
4
|
from .models.config import Config
|
|
4
5
|
from .models.testrun import TestRun
|
|
5
6
|
from .parser import Parser
|
|
@@ -16,11 +17,13 @@ class Service:
|
|
|
16
17
|
api_client: ApiClient,
|
|
17
18
|
parser: Parser,
|
|
18
19
|
importer: Importer,
|
|
20
|
+
autotests_filter: AutotestsFilter
|
|
19
21
|
):
|
|
20
22
|
self.__config = config
|
|
21
23
|
self.__api_client = api_client
|
|
22
24
|
self.__parser = parser
|
|
23
25
|
self.__importer = importer
|
|
26
|
+
self.__autotests_filter = autotests_filter
|
|
24
27
|
|
|
25
28
|
def import_results(self):
|
|
26
29
|
self.__upload_results()
|
|
@@ -33,10 +36,7 @@ class Service:
|
|
|
33
36
|
test_run = self.__create_test_run()
|
|
34
37
|
self.__update_test_run_with_attachments(test_run)
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
with open(self.__config.output, "w") as text_file:
|
|
39
|
-
text_file.write(test_run.id)
|
|
39
|
+
self.__write_to_output(test_run.id)
|
|
40
40
|
|
|
41
41
|
def finished_test_run(self):
|
|
42
42
|
test_run = self.__api_client.get_test_run(self.__config.testrun_id)
|
|
@@ -85,3 +85,14 @@ class Service:
|
|
|
85
85
|
def __update_test_run_with_attachments(self, test_run: TestRun):
|
|
86
86
|
test_run.attachments.extend(self.__upload_attachments())
|
|
87
87
|
self.__api_client.update_test_run(test_run)
|
|
88
|
+
|
|
89
|
+
def __write_to_output(self, content: str):
|
|
90
|
+
DirWorker.create_dir(self.__config.output)
|
|
91
|
+
|
|
92
|
+
with open(self.__config.output, "w") as text_file:
|
|
93
|
+
text_file.write(content)
|
|
94
|
+
|
|
95
|
+
def create_filter_for_test_framework(self):
|
|
96
|
+
autotests_filter = self.__autotests_filter.create_filter()
|
|
97
|
+
|
|
98
|
+
self.__write_to_output(autotests_filter)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from .autotests_filter import AutotestsFilter
|
|
1
2
|
from .logger import Logger
|
|
2
3
|
from .apiclient import ApiClient
|
|
3
4
|
from .importer import Importer
|
|
@@ -7,12 +8,13 @@ from .models.config import Config
|
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class ServiceFactory:
|
|
10
|
-
@
|
|
11
|
-
def get(
|
|
11
|
+
@staticmethod
|
|
12
|
+
def get(config: Config) -> Service:
|
|
12
13
|
Logger.register_logger(config.is_debug)
|
|
13
14
|
|
|
14
15
|
api_client = ApiClient(config.url, config.token, config.disable_cert_validation)
|
|
15
16
|
parser = Parser(config)
|
|
16
17
|
importer = Importer(api_client, config)
|
|
18
|
+
autotests_filter = AutotestsFilter(api_client, config)
|
|
17
19
|
|
|
18
|
-
return Service(config, api_client, parser, importer)
|
|
20
|
+
return Service(config, api_client, parser, importer, autotests_filter)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: testit-cli
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: This tool is the command line wrapper of Test IT allowing you to upload the test results in real time to Test IT
|
|
5
5
|
Home-page: https://pypi.org/project/testit-cli/
|
|
6
6
|
Author: Integration team
|
|
@@ -16,10 +16,19 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: testit-api-client==
|
|
19
|
+
Requires-Dist: testit-api-client==5.0.0
|
|
20
20
|
Requires-Dist: validators
|
|
21
21
|
Requires-Dist: tqdm
|
|
22
22
|
Requires-Dist: click~=8.0.4
|
|
23
|
+
Dynamic: author
|
|
24
|
+
Dynamic: author-email
|
|
25
|
+
Dynamic: classifier
|
|
26
|
+
Dynamic: description
|
|
27
|
+
Dynamic: description-content-type
|
|
28
|
+
Dynamic: home-page
|
|
29
|
+
Dynamic: license
|
|
30
|
+
Dynamic: requires-dist
|
|
31
|
+
Dynamic: summary
|
|
23
32
|
|
|
24
33
|
# Test IT CLI
|
|
25
34
|
|
|
@@ -4,10 +4,12 @@ setup.py
|
|
|
4
4
|
src/testit_cli/__init__.py
|
|
5
5
|
src/testit_cli/__main__.py
|
|
6
6
|
src/testit_cli/apiclient.py
|
|
7
|
+
src/testit_cli/autotests_filter.py
|
|
7
8
|
src/testit_cli/click_commands.py
|
|
8
9
|
src/testit_cli/converter.py
|
|
9
10
|
src/testit_cli/dir_worker.py
|
|
10
11
|
src/testit_cli/file_worker.py
|
|
12
|
+
src/testit_cli/filter_factory.py
|
|
11
13
|
src/testit_cli/importer.py
|
|
12
14
|
src/testit_cli/logger.py
|
|
13
15
|
src/testit_cli/parser.py
|
|
@@ -11,7 +11,7 @@ def runner():
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def test_run_without_command(runner):
|
|
14
|
-
message = "Options:\n --help Show this message and exit.\n\nCommands:\n results
|
|
14
|
+
message = "Options:\n --help Show this message and exit.\n\nCommands:\n autotests_filter Creating filter by autotests for test frameworks\n results Uploading the test results\n testrun Working with the test run\n"
|
|
15
15
|
result = runner.invoke(execute, [])
|
|
16
16
|
|
|
17
17
|
assert message in result.output
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|