pytest-json-ctrf 0.3.2__tar.gz → 0.3.3__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.
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/PKG-INFO +1 -1
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/ctrf/Report.py +10 -2
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/ctrf/TestObject.py +23 -11
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/ctrf/main.py +10 -1
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/pyproject.toml +2 -2
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/pytest_json_ctrf.egg-info/PKG-INFO +1 -1
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/tests/test_example.py +13 -0
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/tests/test_plugin.py +8 -8
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/README.md +0 -0
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/ctrf/BaseMetadataReport.py +0 -0
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/ctrf/CommonTestReportPlugin.py +0 -0
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/ctrf/__init__.py +0 -0
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/pytest_json_ctrf.egg-info/SOURCES.txt +0 -0
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/pytest_json_ctrf.egg-info/dependency_links.txt +0 -0
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/pytest_json_ctrf.egg-info/entry_points.txt +0 -0
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/pytest_json_ctrf.egg-info/requires.txt +0 -0
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/pytest_json_ctrf.egg-info/top_level.txt +0 -0
- {pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/setup.cfg +0 -0
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
import pytest
|
|
3
3
|
import time
|
|
4
4
|
import json
|
|
5
|
+
from typing import Optional
|
|
5
6
|
from pytest import TestReport
|
|
6
7
|
from collections import OrderedDict
|
|
7
8
|
from .TestObject import TestObject, TestStatus
|
|
@@ -54,8 +55,15 @@ class Report:
|
|
|
54
55
|
def process_retries(self) -> None:
|
|
55
56
|
for test_id, test_data in self.test_items.items():
|
|
56
57
|
name = test_id.split('[')[0]
|
|
57
|
-
test = self.prepared_tests.get(name)
|
|
58
|
+
test: Optional[TestObject] = self.prepared_tests.get(name)
|
|
58
59
|
if test:
|
|
60
|
+
test.status = test_data.status
|
|
61
|
+
test.raw_status = test_data.raw_status
|
|
62
|
+
if test_data.status != TestStatus.PASSED:
|
|
63
|
+
test.status = test_data.status
|
|
64
|
+
test.raw_status = test_data.raw_status
|
|
65
|
+
test.message = test_data.message
|
|
66
|
+
test.trace = test_data.trace
|
|
59
67
|
test.retries += 1
|
|
60
68
|
else:
|
|
61
69
|
self.prepared_tests[name] = test_data
|
|
@@ -73,7 +81,7 @@ class Report:
|
|
|
73
81
|
dirname = os.path.dirname(report_file)
|
|
74
82
|
if dirname:
|
|
75
83
|
try:
|
|
76
|
-
os.makedirs(dirname
|
|
84
|
+
os.makedirs(dirname)
|
|
77
85
|
except Exception as e:
|
|
78
86
|
print(e)
|
|
79
87
|
raise Exception(f"Can't create directory {dirname}")
|
|
@@ -14,7 +14,7 @@ class TestStatus(Enum):
|
|
|
14
14
|
|
|
15
15
|
class TestObject:
|
|
16
16
|
name: str
|
|
17
|
-
|
|
17
|
+
_status: TestStatus
|
|
18
18
|
raw_status: str
|
|
19
19
|
duration: float = 0
|
|
20
20
|
start: float
|
|
@@ -30,8 +30,8 @@ class TestObject:
|
|
|
30
30
|
|
|
31
31
|
def __init__(self, report: TestReport, worker_id: str or None = None):
|
|
32
32
|
self.name = report.nodeid.split('[')[0]
|
|
33
|
-
self.
|
|
34
|
-
self.
|
|
33
|
+
self._status = TestStatus.PENDING
|
|
34
|
+
self._status = self.set_status(report)
|
|
35
35
|
self.raw_status = None
|
|
36
36
|
self.duration = 0
|
|
37
37
|
self.start = 0
|
|
@@ -45,13 +45,25 @@ class TestObject:
|
|
|
45
45
|
self.browser = None
|
|
46
46
|
self.trace = None
|
|
47
47
|
|
|
48
|
+
@property
|
|
49
|
+
def status(self) -> TestStatus:
|
|
50
|
+
return self._status
|
|
51
|
+
|
|
52
|
+
@status.setter
|
|
53
|
+
def status(self, value: TestStatus) -> None:
|
|
54
|
+
if self._status in (TestStatus.PENDING, TestStatus.PASSED):
|
|
55
|
+
self._status = value
|
|
56
|
+
return
|
|
57
|
+
elif self._status in (TestStatus.SKIPPED, TestStatus.FAILED):
|
|
58
|
+
return
|
|
59
|
+
|
|
48
60
|
def set_status(self, report: TestReport) -> TestStatus:
|
|
49
|
-
if self.
|
|
50
|
-
return self.
|
|
61
|
+
if self._status in (TestStatus.SKIPPED, TestStatus.FAILED):
|
|
62
|
+
return self._status
|
|
51
63
|
elif report.skipped:
|
|
52
|
-
self.
|
|
64
|
+
self._status = TestStatus.SKIPPED
|
|
53
65
|
elif report.failed:
|
|
54
|
-
self.
|
|
66
|
+
self._status = TestStatus.FAILED
|
|
55
67
|
self.raw_status = f"{report.when}_{report.outcome}"
|
|
56
68
|
self.message = f"The test failed in the {report.when} phase"
|
|
57
69
|
if hasattr(report, 'longreprtext'):
|
|
@@ -60,10 +72,10 @@ class TestObject:
|
|
|
60
72
|
elif "Exception" in report.longreprtext:
|
|
61
73
|
self.message += " due to an exception"
|
|
62
74
|
elif report.passed:
|
|
63
|
-
self.
|
|
75
|
+
self._status = TestStatus.PASSED
|
|
64
76
|
else:
|
|
65
|
-
self.
|
|
66
|
-
return self.
|
|
77
|
+
self._status = TestStatus.OTHER
|
|
78
|
+
return self._status
|
|
67
79
|
|
|
68
80
|
def update(self, report: TestReport) -> None:
|
|
69
81
|
self.set_status(report)
|
|
@@ -81,7 +93,7 @@ class TestObject:
|
|
|
81
93
|
def serialize(self) -> dict:
|
|
82
94
|
result: dict[str, Any] = {
|
|
83
95
|
'name': self.name,
|
|
84
|
-
'status': self.
|
|
96
|
+
'status': self._status.value,
|
|
85
97
|
'raw_status': self.raw_status,
|
|
86
98
|
'duration': self.duration,
|
|
87
99
|
'start': self.start,
|
|
@@ -34,7 +34,16 @@ def pytest_unconfigure(config: Config):
|
|
|
34
34
|
def ctrf_json_metadata(request: FixtureRequest):
|
|
35
35
|
if not request.config.option.ctrf:
|
|
36
36
|
return
|
|
37
|
-
tags =
|
|
37
|
+
tags = list()
|
|
38
|
+
for mark in request.node.iter_markers():
|
|
39
|
+
tag = mark.name
|
|
40
|
+
if mark.args:
|
|
41
|
+
for arg in mark.args:
|
|
42
|
+
tag += f'::{arg}'
|
|
43
|
+
if mark.kwargs:
|
|
44
|
+
for key, value in mark.kwargs.items():
|
|
45
|
+
tag += f'::{key}_{value}'
|
|
46
|
+
tags.append(tag)
|
|
38
47
|
request.node._ctrf_metadata.setdefault('tags', tags)
|
|
39
48
|
if hasattr(request.node, 'callspec'):
|
|
40
49
|
browser = request.node.callspec.params.get('browser_name')
|
|
@@ -10,7 +10,7 @@ exclude = [
|
|
|
10
10
|
|
|
11
11
|
[project]
|
|
12
12
|
name = "pytest-json-ctrf"
|
|
13
|
-
version = "0.3.
|
|
13
|
+
version = "0.3.3"
|
|
14
14
|
|
|
15
15
|
dependencies = [
|
|
16
16
|
"pytest>6.0.0",
|
|
@@ -40,4 +40,4 @@ markers = [
|
|
|
40
40
|
]
|
|
41
41
|
|
|
42
42
|
[project.entry-points.pytest11]
|
|
43
|
-
ctrf = "ctrf.main"
|
|
43
|
+
ctrf = "ctrf.main"
|
|
@@ -50,3 +50,16 @@ def test_do_calculations_8_post_error(post_fail):
|
|
|
50
50
|
@mark.parametrize('param', [1, 2, 3, 4, 5])
|
|
51
51
|
def test_parametrized(param):
|
|
52
52
|
assert param < 10
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@mark.parametrize('param', [6, 7, 8, 9, 10])
|
|
56
|
+
def test_parametrized_fail(param):
|
|
57
|
+
assert param != 8
|
|
58
|
+
|
|
59
|
+
@mark.test_id(1234, hello='world')
|
|
60
|
+
def test_with_test_id():
|
|
61
|
+
assert 1 == 1
|
|
62
|
+
|
|
63
|
+
@mark.test_id(1235)
|
|
64
|
+
def test_with_test_id_2():
|
|
65
|
+
assert 1 == 1
|
|
@@ -25,13 +25,13 @@ def ctrf_report_xdist(pytester: Pytester):
|
|
|
25
25
|
def test_without_plugin_no_xdist(pytester: Pytester):
|
|
26
26
|
pytester.copy_example(test_file)
|
|
27
27
|
result = pytester.runpytest(*basic_test_args)
|
|
28
|
-
result.assert_outcomes(passed=
|
|
28
|
+
result.assert_outcomes(passed=15, skipped=1, failed=3, errors=2)
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def test_without_plugin_with_xdist(pytester: Pytester):
|
|
32
32
|
pytester.copy_example(test_file)
|
|
33
33
|
result = pytester.runpytest(*[*basic_test_args, "-n", "3"])
|
|
34
|
-
result.assert_outcomes(passed=
|
|
34
|
+
result.assert_outcomes(passed=15, skipped=1, failed=3, errors=2)
|
|
35
35
|
assert "created: 3/3 workers" in result.stdout.str()
|
|
36
36
|
|
|
37
37
|
|
|
@@ -48,9 +48,9 @@ def test_with_markers(pytester: Pytester):
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
def test_with_plugin_no_xdist(ctrf_report_sync):
|
|
51
|
-
assert ctrf_report_sync["results"]["summary"]["tests"] ==
|
|
52
|
-
assert ctrf_report_sync["results"]["summary"]["passed"] ==
|
|
53
|
-
assert ctrf_report_sync["results"]["summary"]["failed"] ==
|
|
51
|
+
assert ctrf_report_sync["results"]["summary"]["tests"] == 12
|
|
52
|
+
assert ctrf_report_sync["results"]["summary"]["passed"] == 6
|
|
53
|
+
assert ctrf_report_sync["results"]["summary"]["failed"] == 5
|
|
54
54
|
assert ctrf_report_sync["results"]["summary"]["skipped"] == 1
|
|
55
55
|
|
|
56
56
|
|
|
@@ -70,9 +70,9 @@ def test_any_test_has_timestamps(ctrf_report_sync):
|
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
def test_with_plugin_with_xdist(ctrf_report_xdist):
|
|
73
|
-
assert ctrf_report_xdist["results"]["summary"]["tests"] ==
|
|
74
|
-
assert ctrf_report_xdist["results"]["summary"]["passed"] ==
|
|
75
|
-
assert ctrf_report_xdist["results"]["summary"]["failed"] ==
|
|
73
|
+
assert ctrf_report_xdist["results"]["summary"]["tests"] == 12
|
|
74
|
+
assert ctrf_report_xdist["results"]["summary"]["passed"] == 6
|
|
75
|
+
assert ctrf_report_xdist["results"]["summary"]["failed"] == 5
|
|
76
76
|
assert ctrf_report_xdist["results"]["summary"]["skipped"] == 1
|
|
77
77
|
|
|
78
78
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/pytest_json_ctrf.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{pytest_json_ctrf-0.3.2 → pytest_json_ctrf-0.3.3}/pytest_json_ctrf.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|