schemathesis 4.0.0a3__py3-none-any.whl → 4.0.0a5__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.
- schemathesis/cli/__init__.py +3 -3
- schemathesis/cli/commands/run/__init__.py +159 -135
- schemathesis/cli/commands/run/checks.py +2 -3
- schemathesis/cli/commands/run/context.py +102 -19
- schemathesis/cli/commands/run/executor.py +33 -12
- schemathesis/cli/commands/run/filters.py +1 -0
- schemathesis/cli/commands/run/handlers/cassettes.py +27 -46
- schemathesis/cli/commands/run/handlers/junitxml.py +1 -1
- schemathesis/cli/commands/run/handlers/output.py +238 -102
- schemathesis/cli/commands/run/hypothesis.py +14 -41
- schemathesis/cli/commands/run/reports.py +72 -0
- schemathesis/cli/commands/run/validation.py +18 -12
- schemathesis/cli/ext/groups.py +42 -13
- schemathesis/cli/ext/options.py +15 -8
- schemathesis/core/__init__.py +7 -1
- schemathesis/core/errors.py +79 -11
- schemathesis/core/failures.py +2 -1
- schemathesis/core/transforms.py +1 -1
- schemathesis/engine/config.py +2 -2
- schemathesis/engine/core.py +11 -1
- schemathesis/engine/errors.py +8 -3
- schemathesis/engine/events.py +7 -0
- schemathesis/engine/phases/__init__.py +16 -4
- schemathesis/engine/phases/stateful/_executor.py +1 -1
- schemathesis/engine/phases/unit/__init__.py +77 -53
- schemathesis/engine/phases/unit/_executor.py +28 -23
- schemathesis/engine/phases/unit/_pool.py +8 -0
- schemathesis/errors.py +6 -2
- schemathesis/experimental/__init__.py +0 -6
- schemathesis/filters.py +8 -0
- schemathesis/generation/coverage.py +6 -1
- schemathesis/generation/hypothesis/builder.py +222 -97
- schemathesis/generation/stateful/state_machine.py +49 -3
- schemathesis/openapi/checks.py +3 -1
- schemathesis/pytest/lazy.py +43 -5
- schemathesis/pytest/plugin.py +4 -4
- schemathesis/schemas.py +1 -1
- schemathesis/specs/openapi/checks.py +28 -11
- schemathesis/specs/openapi/examples.py +2 -5
- schemathesis/specs/openapi/expressions/__init__.py +22 -6
- schemathesis/specs/openapi/expressions/nodes.py +15 -21
- schemathesis/specs/openapi/expressions/parser.py +1 -1
- schemathesis/specs/openapi/parameters.py +0 -2
- schemathesis/specs/openapi/patterns.py +24 -7
- schemathesis/specs/openapi/schemas.py +13 -13
- schemathesis/specs/openapi/serialization.py +14 -0
- schemathesis/specs/openapi/stateful/__init__.py +96 -23
- schemathesis/specs/openapi/{links.py → stateful/links.py} +60 -16
- {schemathesis-4.0.0a3.dist-info → schemathesis-4.0.0a5.dist-info}/METADATA +7 -26
- {schemathesis-4.0.0a3.dist-info → schemathesis-4.0.0a5.dist-info}/RECORD +53 -52
- {schemathesis-4.0.0a3.dist-info → schemathesis-4.0.0a5.dist-info}/WHEEL +0 -0
- {schemathesis-4.0.0a3.dist-info → schemathesis-4.0.0a5.dist-info}/entry_points.txt +0 -0
- {schemathesis-4.0.0a3.dist-info → schemathesis-4.0.0a5.dist-info}/licenses/LICENSE +0 -0
schemathesis/cli/__init__.py
CHANGED
@@ -5,7 +5,7 @@ from schemathesis.cli.commands.run.context import ExecutionContext
|
|
5
5
|
from schemathesis.cli.commands.run.events import LoadingFinished, LoadingStarted
|
6
6
|
from schemathesis.cli.commands.run.executor import handler
|
7
7
|
from schemathesis.cli.commands.run.handlers import EventHandler
|
8
|
-
from schemathesis.cli.ext.groups import GROUPS
|
8
|
+
from schemathesis.cli.ext.groups import GROUPS, OptionGroup
|
9
9
|
|
10
10
|
__all__ = [
|
11
11
|
"schemathesis",
|
@@ -22,7 +22,7 @@ __all__ = [
|
|
22
22
|
def add_group(name: str, *, index: int | None = None) -> Group:
|
23
23
|
"""Add a custom options group to `st run`."""
|
24
24
|
if index is not None:
|
25
|
-
GROUPS
|
25
|
+
GROUPS[name] = OptionGroup(name=name, order=index)
|
26
26
|
else:
|
27
|
-
GROUPS
|
27
|
+
GROUPS[name] = OptionGroup(name=name)
|
28
28
|
return Group(name)
|
@@ -1,24 +1,25 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
from pathlib import Path
|
3
4
|
from random import Random
|
4
5
|
from typing import Any, Sequence
|
5
6
|
|
6
7
|
import click
|
8
|
+
from click.utils import LazyFile
|
7
9
|
|
8
10
|
from schemathesis import contrib, experimental
|
9
11
|
from schemathesis.checks import CHECKS
|
10
12
|
from schemathesis.cli.commands.run import executor, validation
|
11
13
|
from schemathesis.cli.commands.run.checks import CheckArguments
|
12
14
|
from schemathesis.cli.commands.run.filters import FilterArguments, with_filters
|
13
|
-
from schemathesis.cli.commands.run.handlers.cassettes import CassetteConfig, CassetteFormat
|
14
15
|
from schemathesis.cli.commands.run.hypothesis import (
|
15
16
|
HYPOTHESIS_IN_MEMORY_DATABASE_IDENTIFIER,
|
16
17
|
HealthCheck,
|
17
|
-
Phase,
|
18
18
|
prepare_health_checks,
|
19
19
|
prepare_phases,
|
20
20
|
prepare_settings,
|
21
21
|
)
|
22
|
+
from schemathesis.cli.commands.run.reports import DEFAULT_REPORT_DIRECTORY, ReportConfig, ReportFormat
|
22
23
|
from schemathesis.cli.constants import DEFAULT_WORKERS, MAX_WORKERS, MIN_WORKERS
|
23
24
|
from schemathesis.cli.core import ensure_color
|
24
25
|
from schemathesis.cli.ext.groups import group, grouped_option
|
@@ -42,32 +43,21 @@ from schemathesis.specs.openapi.checks import * # noqa: F401, F403
|
|
42
43
|
|
43
44
|
COLOR_OPTIONS_INVALID_USAGE_MESSAGE = "Can't use `--no-color` and `--force-color` simultaneously"
|
44
45
|
|
45
|
-
DEFAULT_PHASES = ("
|
46
|
+
DEFAULT_PHASES = ("examples", "coverage", "fuzzing", "stateful")
|
46
47
|
|
47
48
|
|
48
49
|
@click.argument("schema", type=str) # type: ignore[misc]
|
49
50
|
@group("Options")
|
50
51
|
@grouped_option(
|
51
|
-
"--
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
metavar="",
|
56
|
-
)
|
57
|
-
@grouped_option(
|
58
|
-
"--base-url",
|
59
|
-
"-b",
|
60
|
-
help="Base URL of the API, required when schema is provided as a file",
|
52
|
+
"--url",
|
53
|
+
"-u",
|
54
|
+
"base_url",
|
55
|
+
help="API base URL (required for file-based schemas)",
|
56
|
+
metavar="URL",
|
61
57
|
type=str,
|
62
58
|
callback=validation.validate_base_url,
|
63
59
|
envvar="SCHEMATHESIS_BASE_URL",
|
64
60
|
)
|
65
|
-
@grouped_option(
|
66
|
-
"--suppress-health-check",
|
67
|
-
help="A comma-separated list of Schemathesis health checks to disable",
|
68
|
-
type=CsvEnumChoice(HealthCheck),
|
69
|
-
metavar="",
|
70
|
-
)
|
71
61
|
@grouped_option(
|
72
62
|
"--workers",
|
73
63
|
"-w",
|
@@ -82,6 +72,26 @@ DEFAULT_PHASES = ("unit", "stateful")
|
|
82
72
|
callback=validation.convert_workers,
|
83
73
|
metavar="",
|
84
74
|
)
|
75
|
+
@grouped_option(
|
76
|
+
"--phases",
|
77
|
+
help="A comma-separated list of test phases to run",
|
78
|
+
type=CsvChoice(DEFAULT_PHASES),
|
79
|
+
default=",".join(DEFAULT_PHASES),
|
80
|
+
metavar="",
|
81
|
+
)
|
82
|
+
@grouped_option(
|
83
|
+
"--suppress-health-check",
|
84
|
+
help="A comma-separated list of Schemathesis health checks to disable",
|
85
|
+
type=CsvEnumChoice(HealthCheck),
|
86
|
+
metavar="",
|
87
|
+
)
|
88
|
+
@grouped_option(
|
89
|
+
"--wait-for-schema",
|
90
|
+
help="Maximum duration, in seconds, to wait for the API schema to become available. Disabled by default",
|
91
|
+
type=click.FloatRange(1.0),
|
92
|
+
default=None,
|
93
|
+
envvar="SCHEMATHESIS_WAIT_FOR_SCHEMA",
|
94
|
+
)
|
85
95
|
@group("API validation options")
|
86
96
|
@grouped_option(
|
87
97
|
"--checks",
|
@@ -107,62 +117,66 @@ DEFAULT_PHASES = ("unit", "stateful")
|
|
107
117
|
metavar="",
|
108
118
|
)
|
109
119
|
@grouped_option(
|
110
|
-
"--max-
|
111
|
-
|
112
|
-
type=click.
|
120
|
+
"--max-failures",
|
121
|
+
"max_failures",
|
122
|
+
type=click.IntRange(min=1),
|
123
|
+
help="Terminate the test suite after reaching a specified number of failures or errors",
|
124
|
+
show_default=True,
|
113
125
|
)
|
114
126
|
@grouped_option(
|
115
|
-
"-
|
116
|
-
"
|
117
|
-
"
|
127
|
+
"--continue-on-failure",
|
128
|
+
"continue_on_failure",
|
129
|
+
help="Continue executing all test cases within a scenario, even after encountering failures",
|
118
130
|
is_flag=True,
|
119
131
|
default=False,
|
120
|
-
|
121
|
-
show_default=True,
|
132
|
+
metavar="",
|
122
133
|
)
|
123
134
|
@grouped_option(
|
124
|
-
"--max-
|
125
|
-
"
|
126
|
-
type=click.
|
127
|
-
|
128
|
-
|
135
|
+
"--max-response-time",
|
136
|
+
help="Maximum allowed API response time in seconds",
|
137
|
+
type=click.FloatRange(min=0.0, min_open=True),
|
138
|
+
metavar="SECONDS",
|
139
|
+
)
|
140
|
+
@group(
|
141
|
+
"Filtering options",
|
142
|
+
description=(
|
143
|
+
"Filter operations by path, method, name, tag, or operation-id using:\n\n"
|
144
|
+
"--include-TYPE VALUE Match operations with exact VALUE\n"
|
145
|
+
"--include-TYPE-regex PATTERN Match operations using regular expression\n"
|
146
|
+
"--exclude-TYPE VALUE Exclude operations with exact VALUE\n"
|
147
|
+
"--exclude-TYPE-regex PATTERN Exclude operations using regular expression"
|
148
|
+
),
|
129
149
|
)
|
130
|
-
@group("Filtering options")
|
131
150
|
@with_filters
|
132
151
|
@grouped_option(
|
133
152
|
"--include-by",
|
134
153
|
"include_by",
|
135
154
|
type=str,
|
136
|
-
|
155
|
+
metavar="EXPR",
|
156
|
+
help="Include using custom expression",
|
137
157
|
)
|
138
158
|
@grouped_option(
|
139
159
|
"--exclude-by",
|
140
160
|
"exclude_by",
|
141
161
|
type=str,
|
142
|
-
|
162
|
+
metavar="EXPR",
|
163
|
+
help="Exclude using custom expression",
|
143
164
|
)
|
144
165
|
@grouped_option(
|
145
166
|
"--exclude-deprecated",
|
146
|
-
help="
|
167
|
+
help="Skip deprecated operations",
|
147
168
|
is_flag=True,
|
148
169
|
is_eager=True,
|
149
170
|
default=False,
|
150
171
|
show_default=True,
|
151
172
|
)
|
152
|
-
@group("Loader options")
|
153
|
-
@grouped_option(
|
154
|
-
"--wait-for-schema",
|
155
|
-
help="Maximum duration, in seconds, to wait for the API schema to become available. Disabled by default",
|
156
|
-
type=click.FloatRange(1.0),
|
157
|
-
default=None,
|
158
|
-
envvar="SCHEMATHESIS_WAIT_FOR_SCHEMA",
|
159
|
-
)
|
160
173
|
@group("Network requests options")
|
161
174
|
@grouped_option(
|
162
175
|
"--header",
|
163
176
|
"-H",
|
164
177
|
"headers",
|
165
|
-
help=r"Add a custom HTTP header to all API requests
|
178
|
+
help=r"Add a custom HTTP header to all API requests",
|
179
|
+
metavar="NAME:VALUE",
|
166
180
|
multiple=True,
|
167
181
|
type=str,
|
168
182
|
callback=validation.validate_headers,
|
@@ -170,29 +184,40 @@ DEFAULT_PHASES = ("unit", "stateful")
|
|
170
184
|
@grouped_option(
|
171
185
|
"--auth",
|
172
186
|
"-a",
|
173
|
-
help="
|
187
|
+
help="Authenticate all API requests with basic authentication",
|
188
|
+
metavar="USER:PASS",
|
174
189
|
type=str,
|
175
190
|
callback=validation.validate_auth,
|
176
191
|
)
|
177
192
|
@grouped_option(
|
178
|
-
"--
|
179
|
-
|
180
|
-
type=click.FloatRange(min=0.0, min_open=True),
|
181
|
-
default=DEFAULT_RESPONSE_TIMEOUT,
|
182
|
-
)
|
183
|
-
@grouped_option(
|
184
|
-
"--request-proxy",
|
193
|
+
"--proxy",
|
194
|
+
"request_proxy",
|
185
195
|
help="Set the proxy for all network requests",
|
196
|
+
metavar="URL",
|
186
197
|
type=str,
|
187
198
|
)
|
188
199
|
@grouped_option(
|
189
|
-
"--
|
190
|
-
|
200
|
+
"--tls-verify",
|
201
|
+
"request_tls_verify",
|
202
|
+
help="Path to CA bundle for TLS verification, or 'false' to disable",
|
191
203
|
type=str,
|
192
204
|
default="true",
|
193
205
|
show_default=True,
|
194
206
|
callback=validation.convert_boolean_string,
|
195
207
|
)
|
208
|
+
@grouped_option(
|
209
|
+
"--rate-limit",
|
210
|
+
help="Specify a rate limit for test requests in '<limit>/<duration>' format. "
|
211
|
+
"Example - `100/m` for 100 requests per minute",
|
212
|
+
type=str,
|
213
|
+
callback=validation.validate_rate_limit,
|
214
|
+
)
|
215
|
+
@grouped_option(
|
216
|
+
"--request-timeout",
|
217
|
+
help="Timeout limit, in seconds, for each network request during tests",
|
218
|
+
type=click.FloatRange(min=0.0, min_open=True),
|
219
|
+
default=DEFAULT_RESPONSE_TIMEOUT,
|
220
|
+
)
|
196
221
|
@grouped_option(
|
197
222
|
"--request-cert",
|
198
223
|
help="File path of unencrypted client certificate for authentication. "
|
@@ -210,45 +235,56 @@ DEFAULT_PHASES = ("unit", "stateful")
|
|
210
235
|
show_default=False,
|
211
236
|
callback=validation.validate_request_cert_key,
|
212
237
|
)
|
238
|
+
@group("Output options")
|
213
239
|
@grouped_option(
|
214
|
-
"--
|
215
|
-
|
216
|
-
"
|
217
|
-
type=
|
218
|
-
|
240
|
+
"--report",
|
241
|
+
"report_formats",
|
242
|
+
help="Generate test reports in specified formats",
|
243
|
+
type=CsvEnumChoice(ReportFormat),
|
244
|
+
is_eager=True,
|
245
|
+
metavar="FORMAT",
|
219
246
|
)
|
220
|
-
@group("Output options")
|
221
247
|
@grouped_option(
|
222
|
-
"--
|
223
|
-
help="
|
248
|
+
"--report-dir",
|
249
|
+
help="Directory to store all report files",
|
250
|
+
type=click.Path(file_okay=False, dir_okay=True),
|
251
|
+
default=DEFAULT_REPORT_DIRECTORY,
|
252
|
+
show_default=True,
|
253
|
+
)
|
254
|
+
@grouped_option(
|
255
|
+
"--report-junit-path",
|
256
|
+
help="Custom path for JUnit XML report",
|
224
257
|
type=click.File("w", encoding="utf-8"),
|
258
|
+
is_eager=True,
|
225
259
|
)
|
226
260
|
@grouped_option(
|
227
|
-
"--
|
228
|
-
help="
|
261
|
+
"--report-vcr-path",
|
262
|
+
help="Custom path for VCR cassette",
|
229
263
|
type=click.File("w", encoding="utf-8"),
|
230
264
|
is_eager=True,
|
231
265
|
)
|
232
266
|
@grouped_option(
|
233
|
-
"--
|
234
|
-
help="
|
235
|
-
type=click.
|
236
|
-
|
237
|
-
callback=validation.convert_cassette_format,
|
238
|
-
metavar="",
|
267
|
+
"--report-har-path",
|
268
|
+
help="Custom path for HAR file",
|
269
|
+
type=click.File("w", encoding="utf-8"),
|
270
|
+
is_eager=True,
|
239
271
|
)
|
240
272
|
@grouped_option(
|
241
|
-
"--
|
273
|
+
"--report-preserve-bytes",
|
242
274
|
help="Retain exact byte sequence of payloads in cassettes, encoded as base64",
|
275
|
+
type=bool,
|
243
276
|
is_flag=True,
|
244
|
-
|
277
|
+
default=False,
|
278
|
+
callback=validation.validate_preserve_bytes,
|
245
279
|
)
|
246
280
|
@grouped_option(
|
247
281
|
"--output-sanitize",
|
248
|
-
type=
|
249
|
-
default=
|
282
|
+
type=str,
|
283
|
+
default="true",
|
250
284
|
show_default=True,
|
251
285
|
help="Enable or disable automatic output sanitization to obscure sensitive data",
|
286
|
+
metavar="BOOLEAN",
|
287
|
+
callback=validation.convert_boolean_string,
|
252
288
|
)
|
253
289
|
@grouped_option(
|
254
290
|
"--output-truncate",
|
@@ -256,6 +292,7 @@ DEFAULT_PHASES = ("unit", "stateful")
|
|
256
292
|
type=str,
|
257
293
|
default="true",
|
258
294
|
show_default=True,
|
295
|
+
metavar="BOOLEAN",
|
259
296
|
callback=validation.convert_boolean_string,
|
260
297
|
)
|
261
298
|
@group("Experimental options")
|
@@ -268,15 +305,6 @@ DEFAULT_PHASES = ("unit", "stateful")
|
|
268
305
|
multiple=True,
|
269
306
|
metavar="FEATURES",
|
270
307
|
)
|
271
|
-
@grouped_option(
|
272
|
-
"--experimental-no-failfast",
|
273
|
-
"no_failfast",
|
274
|
-
help="Continue testing an API operation after a failure is found",
|
275
|
-
is_flag=True,
|
276
|
-
default=False,
|
277
|
-
metavar="",
|
278
|
-
envvar="SCHEMATHESIS_EXPERIMENTAL_NO_FAILFAST",
|
279
|
-
)
|
280
308
|
@grouped_option(
|
281
309
|
"--experimental-missing-required-header-allowed-statuses",
|
282
310
|
"missing_required_header_allowed_statuses",
|
@@ -306,10 +334,10 @@ DEFAULT_PHASES = ("unit", "stateful")
|
|
306
334
|
)
|
307
335
|
@group("Data generation options")
|
308
336
|
@grouped_option(
|
309
|
-
"--
|
337
|
+
"--mode",
|
338
|
+
"-m",
|
310
339
|
"generation_modes",
|
311
|
-
help="
|
312
|
-
"Use 'positive' for valid data, 'negative' for invalid data, or 'all' for both",
|
340
|
+
help="Test data generation mode",
|
313
341
|
type=click.Choice([item.value for item in GenerationMode] + ["all"]),
|
314
342
|
default=GenerationMode.default().value,
|
315
343
|
callback=validation.convert_generation_mode,
|
@@ -317,14 +345,23 @@ DEFAULT_PHASES = ("unit", "stateful")
|
|
317
345
|
metavar="",
|
318
346
|
)
|
319
347
|
@grouped_option(
|
320
|
-
"--
|
321
|
-
|
348
|
+
"--max-examples",
|
349
|
+
"-n",
|
350
|
+
"generation_max_examples",
|
351
|
+
help="Maximum number of test cases per API operation",
|
352
|
+
type=click.IntRange(1),
|
353
|
+
)
|
354
|
+
@grouped_option(
|
355
|
+
"--seed",
|
356
|
+
"generation_seed",
|
357
|
+
help="Random seed for reproducible test runs",
|
322
358
|
type=int,
|
323
359
|
)
|
324
360
|
@grouped_option(
|
325
|
-
"--
|
326
|
-
|
327
|
-
|
361
|
+
"--no-shrink",
|
362
|
+
"generation_no_shrink",
|
363
|
+
help="Disable test case shrinking. Makes test failures harder to debug but improves performance",
|
364
|
+
is_flag=True,
|
328
365
|
)
|
329
366
|
@grouped_option(
|
330
367
|
"--generation-deterministic",
|
@@ -336,10 +373,11 @@ DEFAULT_PHASES = ("unit", "stateful")
|
|
336
373
|
)
|
337
374
|
@grouped_option(
|
338
375
|
"--generation-allow-x00",
|
339
|
-
help="Whether to allow the generation of
|
376
|
+
help="Whether to allow the generation of 'NULL' bytes within strings",
|
340
377
|
type=str,
|
341
378
|
default="true",
|
342
379
|
show_default=True,
|
380
|
+
metavar="BOOLEAN",
|
343
381
|
callback=validation.convert_boolean_string,
|
344
382
|
)
|
345
383
|
@grouped_option(
|
@@ -350,15 +388,15 @@ DEFAULT_PHASES = ("unit", "stateful")
|
|
350
388
|
callback=validation.validate_generation_codec,
|
351
389
|
)
|
352
390
|
@grouped_option(
|
353
|
-
"--generation-
|
354
|
-
"
|
391
|
+
"--generation-maximize",
|
392
|
+
"generation_maximize",
|
355
393
|
multiple=True,
|
356
394
|
help="Guide input generation to values more likely to expose bugs via targeted property-based testing",
|
357
395
|
type=RegistryChoice(TARGETS),
|
358
396
|
default=None,
|
359
397
|
callback=validation.reduce_list,
|
360
398
|
show_default=True,
|
361
|
-
metavar="
|
399
|
+
metavar="METRIC",
|
362
400
|
)
|
363
401
|
@grouped_option(
|
364
402
|
"--generation-with-security-parameters",
|
@@ -437,19 +475,6 @@ DEFAULT_PHASES = ("unit", "stateful")
|
|
437
475
|
type=str,
|
438
476
|
callback=validation.validate_set_path,
|
439
477
|
)
|
440
|
-
@group("Hypothesis engine options")
|
441
|
-
@grouped_option(
|
442
|
-
"--hypothesis-phases",
|
443
|
-
help="Testing phases to execute",
|
444
|
-
type=CsvEnumChoice(Phase),
|
445
|
-
metavar="",
|
446
|
-
)
|
447
|
-
@grouped_option(
|
448
|
-
"--hypothesis-no-phases",
|
449
|
-
help="Testing phases to exclude from execution",
|
450
|
-
type=CsvEnumChoice(Phase),
|
451
|
-
metavar="",
|
452
|
-
)
|
453
478
|
@group("Global options")
|
454
479
|
@grouped_option("--no-color", help="Disable ANSI color escape codes", type=bool, is_flag=True)
|
455
480
|
@grouped_option("--force-color", help="Explicitly tells to enable ANSI color escape codes", type=bool, is_flag=True)
|
@@ -464,16 +489,15 @@ def run(
|
|
464
489
|
set_cookie: dict[str, str],
|
465
490
|
set_path: dict[str, str],
|
466
491
|
experiments: list,
|
467
|
-
no_failfast: bool,
|
468
492
|
missing_required_header_allowed_statuses: list[str],
|
469
493
|
positive_data_acceptance_allowed_statuses: list[str],
|
470
494
|
negative_data_rejection_allowed_statuses: list[str],
|
471
495
|
included_check_names: Sequence[str],
|
472
496
|
excluded_check_names: Sequence[str],
|
473
|
-
phases: Sequence[str] = DEFAULT_PHASES,
|
474
497
|
max_response_time: float | None = None,
|
475
|
-
|
498
|
+
phases: Sequence[str] = DEFAULT_PHASES,
|
476
499
|
max_failures: int | None = None,
|
500
|
+
continue_on_failure: bool = False,
|
477
501
|
include_path: Sequence[str] = (),
|
478
502
|
include_path_regex: str | None = None,
|
479
503
|
include_method: Sequence[str] = (),
|
@@ -499,27 +523,27 @@ def run(
|
|
499
523
|
exclude_deprecated: bool = False,
|
500
524
|
workers_num: int = DEFAULT_WORKERS,
|
501
525
|
base_url: str | None = None,
|
526
|
+
wait_for_schema: float | None = None,
|
527
|
+
rate_limit: str | None = None,
|
502
528
|
suppress_health_check: list[HealthCheck] | None = None,
|
503
529
|
request_timeout: int | None = None,
|
504
530
|
request_tls_verify: bool = True,
|
505
531
|
request_cert: str | None = None,
|
506
532
|
request_cert_key: str | None = None,
|
507
533
|
request_proxy: str | None = None,
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
534
|
+
report_formats: list[ReportFormat] | None = None,
|
535
|
+
report_dir: Path = DEFAULT_REPORT_DIRECTORY,
|
536
|
+
report_junit_path: LazyFile | None = None,
|
537
|
+
report_vcr_path: LazyFile | None = None,
|
538
|
+
report_har_path: LazyFile | None = None,
|
539
|
+
report_preserve_bytes: bool = False,
|
514
540
|
output_sanitize: bool = True,
|
515
541
|
output_truncate: bool = True,
|
516
542
|
contrib_openapi_fill_missing_examples: bool = False,
|
517
|
-
hypothesis_phases: list[Phase] | None = None,
|
518
|
-
hypothesis_no_phases: list[Phase] | None = None,
|
519
543
|
generation_modes: tuple[GenerationMode, ...] = DEFAULT_GENERATOR_MODES,
|
520
544
|
generation_seed: int | None = None,
|
521
545
|
generation_max_examples: int | None = None,
|
522
|
-
|
546
|
+
generation_maximize: Sequence[str] | None = None,
|
523
547
|
generation_deterministic: bool | None = None,
|
524
548
|
generation_database: str | None = None,
|
525
549
|
generation_unique_inputs: bool = False,
|
@@ -527,6 +551,7 @@ def run(
|
|
527
551
|
generation_graphql_allow_null: bool = True,
|
528
552
|
generation_with_security_parameters: bool = True,
|
529
553
|
generation_codec: str = "utf-8",
|
554
|
+
generation_no_shrink: bool = False,
|
530
555
|
force_color: bool = False,
|
531
556
|
no_color: bool = False,
|
532
557
|
**__kwargs: Any,
|
@@ -541,7 +566,7 @@ def run(
|
|
541
566
|
|
542
567
|
validation.validate_schema(schema, base_url)
|
543
568
|
|
544
|
-
_hypothesis_phases = prepare_phases(
|
569
|
+
_hypothesis_phases = prepare_phases(generation_no_shrink)
|
545
570
|
_hypothesis_suppress_health_check = prepare_health_checks(suppress_health_check)
|
546
571
|
|
547
572
|
for experiment in experiments:
|
@@ -588,16 +613,16 @@ def run(
|
|
588
613
|
max_response_time=max_response_time,
|
589
614
|
).into()
|
590
615
|
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
616
|
+
report_config = None
|
617
|
+
if report_formats or report_junit_path or report_vcr_path or report_har_path:
|
618
|
+
report_config = ReportConfig(
|
619
|
+
formats=report_formats,
|
620
|
+
directory=Path(report_dir),
|
621
|
+
junit_path=report_junit_path if report_junit_path else None,
|
622
|
+
vcr_path=report_vcr_path if report_vcr_path else None,
|
623
|
+
har_path=report_har_path if report_har_path else None,
|
624
|
+
preserve_bytes=report_preserve_bytes,
|
599
625
|
sanitize_output=output_sanitize,
|
600
|
-
preserve_exact_body_bytes=cassette_preserve_exact_body_bytes,
|
601
626
|
)
|
602
627
|
|
603
628
|
# Use the same seed for all tests unless `derandomize=True` is used
|
@@ -616,7 +641,7 @@ def run(
|
|
616
641
|
execution=ExecutionConfig(
|
617
642
|
phases=phases_,
|
618
643
|
checks=selected_checks,
|
619
|
-
targets=TARGETS.get_by_names(
|
644
|
+
targets=TARGETS.get_by_names(generation_maximize or []),
|
620
645
|
hypothesis_settings=prepare_settings(
|
621
646
|
database=generation_database,
|
622
647
|
derandomize=generation_deterministic,
|
@@ -632,7 +657,7 @@ def run(
|
|
632
657
|
with_security_parameters=generation_with_security_parameters,
|
633
658
|
),
|
634
659
|
max_failures=max_failures,
|
635
|
-
|
660
|
+
continue_on_failure=continue_on_failure,
|
636
661
|
unique_inputs=generation_unique_inputs,
|
637
662
|
seed=seed,
|
638
663
|
workers_num=workers_num,
|
@@ -654,8 +679,7 @@ def run(
|
|
654
679
|
wait_for_schema=wait_for_schema,
|
655
680
|
rate_limit=rate_limit,
|
656
681
|
output=OutputConfig(sanitize=output_sanitize, truncate=output_truncate),
|
657
|
-
|
658
|
-
junit_xml=junit_xml,
|
682
|
+
report=report_config,
|
659
683
|
args=ctx.args,
|
660
684
|
params=ctx.params,
|
661
685
|
)
|
@@ -69,10 +69,9 @@ class CheckArguments:
|
|
69
69
|
checks_config[_max_response_time] = MaxResponseTimeConfig(self.max_response_time)
|
70
70
|
selected_checks.append(_max_response_time)
|
71
71
|
|
72
|
-
|
73
|
-
from schemathesis.specs.openapi.checks import unsupported_method
|
72
|
+
from schemathesis.specs.openapi.checks import unsupported_method
|
74
73
|
|
75
|
-
|
74
|
+
selected_checks.append(unsupported_method)
|
76
75
|
|
77
76
|
# Exclude checks based on their names
|
78
77
|
selected_checks = [check for check in selected_checks if check.__name__ not in self.excluded_check_names]
|