pytest-json-ctrf 0.6.2__tar.gz → 0.6.4__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 (18) hide show
  1. {pytest_json_ctrf-0.6.2/pytest_json_ctrf.egg-info → pytest_json_ctrf-0.6.4}/PKG-INFO +6 -1
  2. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/README.md +5 -0
  3. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/ctrf/Report.py +11 -2
  4. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/ctrf/TestObject.py +9 -2
  5. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/pyproject.toml +3 -1
  6. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4/pytest_json_ctrf.egg-info}/PKG-INFO +6 -1
  7. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/LICENSE +0 -0
  8. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/MANIFEST.in +0 -0
  9. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/ctrf/BaseMetadataReport.py +0 -0
  10. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/ctrf/CommonTestReportPlugin.py +0 -0
  11. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/ctrf/__init__.py +0 -0
  12. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/ctrf/main.py +0 -0
  13. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/pytest_json_ctrf.egg-info/SOURCES.txt +0 -0
  14. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/pytest_json_ctrf.egg-info/dependency_links.txt +0 -0
  15. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/pytest_json_ctrf.egg-info/entry_points.txt +0 -0
  16. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/pytest_json_ctrf.egg-info/requires.txt +0 -0
  17. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/pytest_json_ctrf.egg-info/top_level.txt +0 -0
  18. {pytest_json_ctrf-0.6.2 → pytest_json_ctrf-0.6.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-json-ctrf
3
- Version: 0.6.2
3
+ Version: 0.6.4
4
4
  Summary: Pytest plugin to generate json report in CTRF (Common Test Report Format)
5
5
  Author: Oleksii Ostapov
6
6
  License-Expression: MIT
@@ -132,6 +132,11 @@ The `pytest_runtest_logreport` hook in the controller node is used to collect th
132
132
  - https://github.com/infopulse/Playwright-course-python -> The report will be used in the demo project as +1 report option
133
133
 
134
134
  ## Changelog
135
+ - 0.6.4 - summary `duration` is measured on a monotonic clock, so it stays correct when time-machine or freezegun travel is still active at the end of the session
136
+ - summary `start` and `stop` are still wall-clock timestamps and are shifted under that travel, so `duration` can differ from `stop - start`
137
+ - 0.6.3 - fixed issue 7 - test and retry attempt `duration` is the sum of pytest's monotonic phase durations, so it stays correct when a time-travel library such as time-machine moves the wall clock between tests
138
+ - `start` and `stop` are still wall-clock timestamps, so `duration` can differ from `stop - start`
139
+ - time between phases (report hooks, failure formatting) is no longer counted
135
140
  - 0.6.2 - minimum versions are now pytest 7.4 and Python 3.9 (drops Python 3.8). pytest 6.x failed at startup, even without `--ctrf`; 7.0–7.2 failed when `--ctrf` was used; 7.3 worked, but reported `pytest.fail(..., pytrace=False)` messages without the `Failed: ` prefix
136
141
  - 0.6.1 - proper license added to the package to fix build pipeline warnings
137
142
  - 0.6.0 - fixed issue 12 - report now validates against the CTRF schema. Thanks to [@jamesarosen](https://github.com/jamesarosen) for the detailed report!
@@ -115,6 +115,11 @@ The `pytest_runtest_logreport` hook in the controller node is used to collect th
115
115
  - https://github.com/infopulse/Playwright-course-python -> The report will be used in the demo project as +1 report option
116
116
 
117
117
  ## Changelog
118
+ - 0.6.4 - summary `duration` is measured on a monotonic clock, so it stays correct when time-machine or freezegun travel is still active at the end of the session
119
+ - summary `start` and `stop` are still wall-clock timestamps and are shifted under that travel, so `duration` can differ from `stop - start`
120
+ - 0.6.3 - fixed issue 7 - test and retry attempt `duration` is the sum of pytest's monotonic phase durations, so it stays correct when a time-travel library such as time-machine moves the wall clock between tests
121
+ - `start` and `stop` are still wall-clock timestamps, so `duration` can differ from `stop - start`
122
+ - time between phases (report hooks, failure formatting) is no longer counted
118
123
  - 0.6.2 - minimum versions are now pytest 7.4 and Python 3.9 (drops Python 3.8). pytest 6.x failed at startup, even without `--ctrf`; 7.0–7.2 failed when `--ctrf` was used; 7.3 worked, but reported `pytest.fail(..., pytrace=False)` messages without the `Failed: ` prefix
119
124
  - 0.6.1 - proper license added to the package to fix build pipeline warnings
120
125
  - 0.6.0 - fixed issue 12 - report now validates against the CTRF schema. Thanks to [@jamesarosen](https://github.com/jamesarosen) for the detailed report!
@@ -13,16 +13,24 @@ from .TestObject import TestObject, TestStatus
13
13
 
14
14
 
15
15
  class Report:
16
+ # held on the class because freezegun replaces time.perf_counter and every module-level reference to it
17
+ _perf_counter = staticmethod(time.perf_counter)
18
+
16
19
  def __init__(self):
17
20
  self.test_items = OrderedDict()
18
21
  self.start_time = None
19
22
  self.stop_time = None
23
+ self._start_perf = None
24
+ self._duration_s = None
20
25
 
21
26
  def start(self) -> None:
22
27
  self.start_time = int(time.time() * 1000)
28
+ self._start_perf = self._perf_counter()
23
29
 
24
30
  def stop(self) -> None:
25
31
  self.stop_time = int(time.time() * 1000)
32
+ if self._start_perf is not None:
33
+ self._duration_s = self._perf_counter() - self._start_perf
26
34
 
27
35
  @staticmethod
28
36
  def _get_tool() -> dict:
@@ -49,8 +57,9 @@ class Report:
49
57
  'start': self.start_time,
50
58
  'stop': self.stop_time,
51
59
  }
52
- if self.start_time is not None and self.stop_time is not None:
53
- summary['duration'] = self.stop_time - self.start_time
60
+ # duration is monotonic, so unlike the wall-clock start/stop it survives time travel; it need not equal stop - start
61
+ if self._duration_s is not None:
62
+ summary['duration'] = round(self._duration_s * 1000)
54
63
  return summary
55
64
 
56
65
  @staticmethod
@@ -18,6 +18,7 @@ class TestObject:
18
18
  raw_status: Optional[str]
19
19
  start: int
20
20
  stop: int
21
+ _duration_s: float
21
22
  retries: int
22
23
  message: Optional[str]
23
24
 
@@ -48,6 +49,7 @@ class TestObject:
48
49
  self.trace = None
49
50
  self.start = 0
50
51
  self.stop = 0
52
+ self._duration_s = 0.0
51
53
  self._setup_seen = False
52
54
 
53
55
  @staticmethod
@@ -73,7 +75,7 @@ class TestObject:
73
75
  attempt = {
74
76
  'attempt': len(self.retry_attempts) + 1,
75
77
  'status': self._status.value,
76
- 'duration': max(self.stop - self.start, 0),
78
+ 'duration': round(self._duration_s * 1000),
77
79
  'start': self.start,
78
80
  'stop': self.stop,
79
81
  'message': self.message,
@@ -133,6 +135,11 @@ class TestObject:
133
135
  self._finish_attempt()
134
136
  self._setup_seen = True
135
137
  self.start = int(report.start * 1000)
138
+ # report.duration is monotonic, unlike the wall-clock start/stop.
139
+ # SubtestReport (pytest>=9) and pytest-subtests' SubTestReport carry a context;
140
+ # their time is already counted in the parent test's call phase
141
+ if not hasattr(report, 'context'):
142
+ self._duration_s += report.duration
136
143
  self.set_status(report)
137
144
  if report.when == "teardown":
138
145
  self.stop = int(report.stop * 1000)
@@ -146,7 +153,7 @@ class TestObject:
146
153
  'name': self.name,
147
154
  'status': self._status.value,
148
155
  'rawStatus': self.raw_status,
149
- 'duration': self.stop - self.start,
156
+ 'duration': round(self._duration_s * 1000),
150
157
  'start': self.start,
151
158
  'stop': self.stop,
152
159
  'suite': self.suite,
@@ -10,7 +10,7 @@ exclude = [
10
10
 
11
11
  [project]
12
12
  name = "pytest-json-ctrf"
13
- version = "0.6.2"
13
+ version = "0.6.4"
14
14
 
15
15
  # minimum pytest and Python versions: keep in sync with .github/workflows/deploy.yml and the README
16
16
  dependencies = [
@@ -45,7 +45,9 @@ ctrf = "ctrf.main"
45
45
 
46
46
  [dependency-groups]
47
47
  dev = [
48
+ "freezegun>=1.5",
48
49
  "jsonschema>=4.23.0",
49
50
  "pytest-rerunfailures>=14.0",
50
51
  "pytest-xdist>=3.6.1",
52
+ "time-machine>=2.10",
51
53
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-json-ctrf
3
- Version: 0.6.2
3
+ Version: 0.6.4
4
4
  Summary: Pytest plugin to generate json report in CTRF (Common Test Report Format)
5
5
  Author: Oleksii Ostapov
6
6
  License-Expression: MIT
@@ -132,6 +132,11 @@ The `pytest_runtest_logreport` hook in the controller node is used to collect th
132
132
  - https://github.com/infopulse/Playwright-course-python -> The report will be used in the demo project as +1 report option
133
133
 
134
134
  ## Changelog
135
+ - 0.6.4 - summary `duration` is measured on a monotonic clock, so it stays correct when time-machine or freezegun travel is still active at the end of the session
136
+ - summary `start` and `stop` are still wall-clock timestamps and are shifted under that travel, so `duration` can differ from `stop - start`
137
+ - 0.6.3 - fixed issue 7 - test and retry attempt `duration` is the sum of pytest's monotonic phase durations, so it stays correct when a time-travel library such as time-machine moves the wall clock between tests
138
+ - `start` and `stop` are still wall-clock timestamps, so `duration` can differ from `stop - start`
139
+ - time between phases (report hooks, failure formatting) is no longer counted
135
140
  - 0.6.2 - minimum versions are now pytest 7.4 and Python 3.9 (drops Python 3.8). pytest 6.x failed at startup, even without `--ctrf`; 7.0–7.2 failed when `--ctrf` was used; 7.3 worked, but reported `pytest.fail(..., pytrace=False)` messages without the `Failed: ` prefix
136
141
  - 0.6.1 - proper license added to the package to fix build pipeline warnings
137
142
  - 0.6.0 - fixed issue 12 - report now validates against the CTRF schema. Thanks to [@jamesarosen](https://github.com/jamesarosen) for the detailed report!