schemathesis 3.39.1__py3-none-any.whl → 3.39.2__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.
@@ -24,7 +24,7 @@ if TYPE_CHECKING:
24
24
  @dataclass
25
25
  class JunitXMLHandler(EventHandler):
26
26
  file_handle: LazyFile
27
- test_cases: list = field(default_factory=list)
27
+ test_cases: dict = field(default_factory=dict)
28
28
 
29
29
  def handle_event(self, context: ExecutionContext, event: events.ExecutionEvent) -> None:
30
30
  if isinstance(event, (events.AfterExecution, events.AfterStatefulExecution)):
@@ -33,23 +33,31 @@ class JunitXMLHandler(EventHandler):
33
33
  name = f"{event_.result.method} {event_.result.path}"
34
34
  else:
35
35
  name = event_.result.verbose_name
36
- test_case = TestCase(name, elapsed_sec=event_.elapsed_time, allow_multiple_subelements=True)
36
+ if name in self.test_cases:
37
+ test_case = self.test_cases[name]
38
+ test_case.elapsed_sec += event_.elapsed_time
39
+ else:
40
+ test_case = TestCase(name, elapsed_sec=event_.elapsed_time, allow_multiple_subelements=True)
37
41
  if event_.status == Status.failure:
38
42
  _add_failure(test_case, event_.result.checks, context)
39
43
  elif event_.status == Status.error:
40
- test_case.add_error_info(message=build_error_message(context, event_.result.errors[-1]))
44
+ test_case.add_error_info(output=build_error_message(context, event_.result.errors[-1]))
41
45
  elif event_.status == Status.skip:
42
- test_case.add_skipped_info(message=event_.result.skip_reason)
43
- self.test_cases.append(test_case)
46
+ test_case.add_skipped_info(output=event_.result.skip_reason)
47
+ self.test_cases[name] = test_case
44
48
  elif isinstance(event, events.Finished):
45
- test_suites = [TestSuite("schemathesis", test_cases=self.test_cases, hostname=platform.node())]
49
+ test_suites = [
50
+ TestSuite("schemathesis", test_cases=list(self.test_cases.values()), hostname=platform.node())
51
+ ]
46
52
  to_xml_report_file(file_descriptor=self.file_handle, test_suites=test_suites, prettyprint=True)
47
53
 
48
54
 
49
55
  def _add_failure(test_case: TestCase, checks: list[SerializedCheck], context: ExecutionContext) -> None:
56
+ messages = []
50
57
  for idx, (code_sample, group) in enumerate(group_by_case(checks, context.code_sample_style), 1):
51
58
  checks = sorted(group, key=lambda c: c.name != "not_a_server_error")
52
- test_case.add_failure_info(message=build_failure_message(context, idx, code_sample, checks))
59
+ messages.append(build_failure_message(context, idx, code_sample, checks))
60
+ test_case.add_failure_info(message="\n\n".join(messages))
53
61
 
54
62
 
55
63
  def build_failure_message(context: ExecutionContext, idx: int, code_sample: str, checks: list[SerializedCheck]) -> str:
@@ -317,7 +317,7 @@ def use_after_free(ctx: CheckContext, response: GenericResponse, original: Case)
317
317
 
318
318
  if not isinstance(original.operation.schema, BaseOpenAPISchema):
319
319
  return True
320
- if response.status_code == 404 or not original.source:
320
+ if response.status_code == 404 or not original.source or response.status_code >= 500:
321
321
  return None
322
322
  response = original.source.response
323
323
  case = original.source.case
@@ -160,6 +160,9 @@ class BaseOpenAPISchema(BaseSchema):
160
160
  ) -> bool:
161
161
  if method not in HTTP_METHODS:
162
162
  return True
163
+ if self.filter_set.is_empty():
164
+ return False
165
+ path = self.get_full_path(path)
163
166
  # Attribute assignment is way faster than creating a new namespace every time
164
167
  operation = _ctx_cache.operation
165
168
  operation.method = method
@@ -175,17 +178,15 @@ class BaseOpenAPISchema(BaseSchema):
175
178
  paths = self.raw_schema["paths"]
176
179
  except KeyError:
177
180
  return
178
- get_full_path = self.get_full_path
179
181
  resolve = self.resolver.resolve
180
182
  should_skip = self._should_skip
181
183
  for path, path_item in paths.items():
182
- full_path = get_full_path(path)
183
184
  try:
184
185
  if "$ref" in path_item:
185
186
  _, path_item = resolve(path_item["$ref"])
186
187
  # Straightforward iteration is faster than converting to a set & calculating length.
187
188
  for method, definition in path_item.items():
188
- if should_skip(full_path, method, definition):
189
+ if should_skip(path, method, definition):
189
190
  continue
190
191
  yield definition
191
192
  except SCHEMA_PARSING_ERRORS:
@@ -282,7 +283,6 @@ class BaseOpenAPISchema(BaseSchema):
282
283
 
283
284
  context = HookContext()
284
285
  # Optimization: local variables are faster than attribute access
285
- get_full_path = self.get_full_path
286
286
  dispatch_hook = self.dispatch_hook
287
287
  resolve_path_item = self._resolve_path_item
288
288
  resolve_shared_parameters = self._resolve_shared_parameters
@@ -294,7 +294,6 @@ class BaseOpenAPISchema(BaseSchema):
294
294
  for path, path_item in paths.items():
295
295
  method = None
296
296
  try:
297
- full_path = get_full_path(path) # Should be available for later use
298
297
  dispatch_hook("before_process_path", context, path, path_item)
299
298
  scope, path_item = resolve_path_item(path_item)
300
299
  with in_scope(self.resolver, scope):
@@ -304,7 +303,7 @@ class BaseOpenAPISchema(BaseSchema):
304
303
  continue
305
304
  try:
306
305
  resolved = resolve_operation(entry)
307
- if should_skip(full_path, method, resolved):
306
+ if should_skip(path, method, resolved):
308
307
  continue
309
308
  parameters = resolved.get("parameters", ())
310
309
  parameters = collect_parameters(itertools.chain(parameters, shared_parameters), resolved)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: schemathesis
3
- Version: 3.39.1
3
+ Version: 3.39.2
4
4
  Summary: Property-based testing framework for Open API and GraphQL based apps
5
5
  Project-URL: Documentation, https://schemathesis.readthedocs.io/en/stable/
6
6
  Project-URL: Changelog, https://schemathesis.readthedocs.io/en/stable/changelog.html
@@ -41,7 +41,7 @@ Requires-Dist: hypothesis[zoneinfo]<7,>=6.103.4; python_version == '3.8'
41
41
  Requires-Dist: jsonschema[format]<5.0,>=4.18.0
42
42
  Requires-Dist: junit-xml<2.0,>=1.9
43
43
  Requires-Dist: pyrate-limiter<4.0,>=2.10
44
- Requires-Dist: pytest-subtests<0.14.0,>=0.2.1
44
+ Requires-Dist: pytest-subtests<0.15.0,>=0.2.1
45
45
  Requires-Dist: pytest<9,>=4.6.4
46
46
  Requires-Dist: pyyaml<7.0,>=5.1
47
47
  Requires-Dist: requests<3,>=2.22
@@ -36,7 +36,7 @@ schemathesis/cli/constants.py,sha256=wk-0GsoJIel8wFFerQ6Kf_6eAYUtIWkwMFwyAqv3yj4
36
36
  schemathesis/cli/context.py,sha256=j_lvYQiPa6Q7P4P_IGCM9V2y2gJSpDbpxIIzR5oFB2I,2567
37
37
  schemathesis/cli/debug.py,sha256=_YA-bX1ujHl4bqQDEum7M-I2XHBTEGbvgkhvcvKhmgU,658
38
38
  schemathesis/cli/handlers.py,sha256=EXSAFe5TQlHANz1AVlSttfsoDT2oeaeFbqq1N7e2udw,467
39
- schemathesis/cli/junitxml.py,sha256=iWbD5G2mzxrLiC24OuGHCLwkgHQg80OXY00stnGaXL0,5054
39
+ schemathesis/cli/junitxml.py,sha256=_psBdqGwH4OKySSWeva41mbgGLav86UnWhQyOt99gnU,5331
40
40
  schemathesis/cli/options.py,sha256=yL7nrzKkbGCc4nQya9wpTW48XGz_OT9hOFrzPxRrDe4,2853
41
41
  schemathesis/cli/reporting.py,sha256=KC3sxSc1u4aFQ-0Q8CQ3G4HTEl7QxlubGnJgNKmVJdQ,3627
42
42
  schemathesis/cli/sanitization.py,sha256=Onw_NWZSom6XTVNJ5NHnC0PAhrYAcGzIXJbsBCzLkn4,1005
@@ -107,7 +107,7 @@ schemathesis/specs/graphql/validation.py,sha256=uINIOt-2E7ZuQV2CxKzwez-7L9tDtqzM
107
107
  schemathesis/specs/openapi/__init__.py,sha256=HDcx3bqpa6qWPpyMrxAbM3uTo0Lqpg-BUNZhDJSJKnw,279
108
108
  schemathesis/specs/openapi/_cache.py,sha256=PAiAu4X_a2PQgD2lG5H3iisXdyg4SaHpU46bRZvfNkM,4320
109
109
  schemathesis/specs/openapi/_hypothesis.py,sha256=nU8UDn1PzGCre4IVmwIuO9-CZv1KJe1fYY0d2BojhSo,22981
110
- schemathesis/specs/openapi/checks.py,sha256=6FMWic9JHF1DsIieYjx5qIdeKeddsw-Jlb7HuK-Ifdw,25318
110
+ schemathesis/specs/openapi/checks.py,sha256=fWtI7rq4wi6qK2E9U_hdJlIyIBVTCB4Klh_3hrCNsps,25349
111
111
  schemathesis/specs/openapi/constants.py,sha256=JqM_FHOenqS_MuUE9sxVQ8Hnw0DNM8cnKDwCwPLhID4,783
112
112
  schemathesis/specs/openapi/converter.py,sha256=Yxw9lS_JKEyi-oJuACT07fm04bqQDlAu-iHwzkeDvE4,3546
113
113
  schemathesis/specs/openapi/definitions.py,sha256=WTkWwCgTc3OMxfKsqh6YDoGfZMTThSYrHGp8h0vLAK0,93935
@@ -119,7 +119,7 @@ schemathesis/specs/openapi/media_types.py,sha256=dNTxpRQbY3SubdVjh4Cjb38R6Bc9MF9
119
119
  schemathesis/specs/openapi/parameters.py,sha256=LUahlWKCDSlp94v2IA1Q90pyeECgO6FmrqbzCU-9Z0Y,14658
120
120
  schemathesis/specs/openapi/patterns.py,sha256=aEOiJeqI_qcE9bE2Viz6TUA8UppiTHm6QFxrLJryag8,5520
121
121
  schemathesis/specs/openapi/references.py,sha256=euxM02kQGMHh4Ss1jWjOY_gyw_HazafKITIsvOEiAvI,9831
122
- schemathesis/specs/openapi/schemas.py,sha256=MLU2h9DrQNCDkk74MFFSj-8BsKjkJsf9lJQHPxLFVps,53845
122
+ schemathesis/specs/openapi/schemas.py,sha256=JA9SiBnwYg75kYnd4_0CWOuQv_XTfYwuDeGmFe4RtVo,53724
123
123
  schemathesis/specs/openapi/security.py,sha256=Z-6pk2Ga1PTUtBe298KunjVHsNh5A-teegeso7zcPIE,7138
124
124
  schemathesis/specs/openapi/serialization.py,sha256=5qGdFHZ3n80UlbSXrO_bkr4Al_7ci_Z3aSUjZczNDQY,11384
125
125
  schemathesis/specs/openapi/utils.py,sha256=ER4vJkdFVDIE7aKyxyYatuuHVRNutytezgE52pqZNE8,900
@@ -153,8 +153,8 @@ schemathesis/transports/auth.py,sha256=urSTO9zgFO1qU69xvnKHPFQV0SlJL3d7_Ojl0tLnZ
153
153
  schemathesis/transports/content_types.py,sha256=MiKOm-Hy5i75hrROPdpiBZPOTDzOwlCdnthJD12AJzI,2187
154
154
  schemathesis/transports/headers.py,sha256=hr_AIDOfUxsJxpHfemIZ_uNG3_vzS_ZeMEKmZjbYiBE,990
155
155
  schemathesis/transports/responses.py,sha256=OFD4ZLqwEFpo7F9vaP_SVgjhxAqatxIj38FS4XVq8Qs,1680
156
- schemathesis-3.39.1.dist-info/METADATA,sha256=nlt5mHbH7Af2CKtH8Ah7flGWMEA5faS72Mo1QVK1v3Y,12956
157
- schemathesis-3.39.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
158
- schemathesis-3.39.1.dist-info/entry_points.txt,sha256=VHyLcOG7co0nOeuk8WjgpRETk5P1E2iCLrn26Zkn5uk,158
159
- schemathesis-3.39.1.dist-info/licenses/LICENSE,sha256=PsPYgrDhZ7g9uwihJXNG-XVb55wj2uYhkl2DD8oAzY0,1103
160
- schemathesis-3.39.1.dist-info/RECORD,,
156
+ schemathesis-3.39.2.dist-info/METADATA,sha256=mrOeTevX0mrdFm-n_sjh0MIHgKaOS-QCk8KvPDMOxL0,12956
157
+ schemathesis-3.39.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
158
+ schemathesis-3.39.2.dist-info/entry_points.txt,sha256=VHyLcOG7co0nOeuk8WjgpRETk5P1E2iCLrn26Zkn5uk,158
159
+ schemathesis-3.39.2.dist-info/licenses/LICENSE,sha256=PsPYgrDhZ7g9uwihJXNG-XVb55wj2uYhkl2DD8oAzY0,1103
160
+ schemathesis-3.39.2.dist-info/RECORD,,