Source code for swaggerconformance._basictests
"""
Main high-level entrypoints for validating swagger conformance.
"""
import logging
import traceback
import hypothesis
from .client import Client
from .strategies import StrategyFactory
__all__ = ["api_conformance_test", "operation_conformance_test"]
log = logging.getLogger(__name__)
[docs]def api_conformance_test(schema_path, num_tests_per_op=20, cont_on_err=True):
"""Basic test of the conformance of the API defined by the given schema.
:param schema_path: The path to / URL of the schema to validate.
:type schema_path: str
:param num_tests_per_op: How many tests to run of each API operation.
:type num_tests_per_op: int
:param cont_on_err: Validate all operations, or drop out on first error.
:type cont_on_err: bool
"""
client = Client(schema_path)
log.debug("Expanded endpoints as: %r", client.api)
hit_errors = []
for operation in client.api.operations():
try:
operation_conformance_test(client, operation, num_tests_per_op)
except Exception: # pylint: disable=broad-except
log.exception("Validation failed of operation: %r", operation)
hit_errors.append(traceback.format_exc())
if not cont_on_err:
raise
if len(hit_errors) > 0:
raise Exception("{} operation(s) failed conformance tests - check "
"output in logging and tracebacks below for "
"details\n{}".format(len(hit_errors),
'\n'.join(hit_errors)))
[docs]def operation_conformance_test(client, operation, num_tests=20):
"""Test the conformance of the given operation using the provided client.
:param client: The client to use to access the API.
:type client: client.Client
:param operation: The operation to test.
:type operation: schema.Operation
:param num_tests: How many tests to run of each API operation.
:type num_tests: int
"""
log.info("Testing operation: %r", operation)
strategy = operation.parameters_strategy(StrategyFactory())
@hypothesis.settings(
max_examples=num_tests,
suppress_health_check=[hypothesis.HealthCheck.too_slow])
@hypothesis.given(strategy)
def single_operation_test(client, operation, params):
"""Test an operation fully.
:param client: The client to use to access the API.
:type client: client.Client
:param operation: The operation to test.
:type operation: schema.Operation
:param params: The dictionary of parameters to use on the operation.
:type params: dict
"""
log.info("Testing with params: %r", params)
result = client.request(operation, params)
assert result.status in operation.response_codes, \
"Response code {} not in {}".format(result.status,
operation.response_codes)
assert any(entry.strip().startswith('application/json') \
for entry in result.headers['Content-Type']), \
"'application/json' not in 'Content-Type' header: {}" \
.format(result.headers['Content-Type'])
# Run the test, which takes one less parameter than expected due to the
# hypothesis decorator providing the last one.
single_operation_test(client, operation) # pylint: disable=E1120