示例#1
0
def test_url_joining(request, server, get_schema_path, schema_path):
    if schema_path == "petstore_v2.yaml":
        base_url = request.getfixturevalue("openapi2_base_url")
    else:
        base_url = request.getfixturevalue("openapi3_base_url")
    path = get_schema_path(schema_path)
    schema = oas_loaders.from_path(path, base_url=f"{base_url}/v3", endpoint="/pet/findByStatus")
    *_, after_execution, _ = from_schema(schema, hypothesis_settings=hypothesis.settings(max_examples=1)).execute()
    assert after_execution.result.path == "/api/v3/pet/findByStatus"
    assert (
        f"http://127.0.0.1:{server['port']}/api/v3/pet/findByStatus"
        in after_execution.result.checks[0].example.requests_code
    )
示例#2
0
def test_number_deserializing(testdir):
    # When numbers in a schema are written in scientific notation but without a dot
    # (achieved by dumping the schema with json.dumps)
    schema = {
        "openapi": "3.0.2",
        "info": {
            "title": "Test",
            "description": "Test",
            "version": "0.1.0"
        },
        "paths": {
            "/teapot": {
                "get": {
                    "summary":
                    "Test",
                    "parameters": [{
                        "name": "key",
                        "in": "query",
                        "required": True,
                        "schema": {
                            "type": "number",
                            "multipleOf": 0.00001
                        },
                    }],
                    "responses": {
                        "200": {
                            "description": "OK"
                        }
                    },
                }
            }
        },
    }

    schema_path = testdir.makefile(".yaml", schema=json.dumps(schema))
    # Then yaml loader should parse them without schema validation errors
    parsed = loaders.from_path(str(schema_path))
    # and the value should be a number
    value = parsed.raw_schema["paths"]["/teapot"]["get"]["parameters"][0][
        "schema"]["multipleOf"]
    assert isinstance(value, float)
示例#3
0
def test_runner(schema_path):
    schema = loaders.from_path(schema_path, validate_schema=False)
    runner = from_schema(
        schema,
        dry_run=True,
        count_operations=False,
        hypothesis_settings=hypothesis.settings(
            max_examples=1, suppress_health_check=HealthCheck.all(), phases=[Phase.explicit, Phase.generate]
        ),
    )

    schema_id = get_id(schema_path)

    def check_xfailed(ev) -> bool:
        if schema_id in XFAILING and ev.current_operation in XFAILING[schema_id]:
            if ev.result.errors:
                message = XFAILING[schema_id][ev.current_operation]
                # If is is failed for some other reason, then an assertion will be risen
                return any(message in err.exception_with_traceback for err in ev.result.errors)
            pytest.fail("Expected a failure")
        return False

    def is_unsatisfiable(text):
        return "Unable to satisfy schema parameters for this API operation" in text

    def check_flaky(ev) -> bool:
        if schema_id in FLAKY_SCHEMAS and ev.current_operation in FLAKY_SCHEMAS[schema_id]:
            if ev.result.errors:
                # NOTE. There could be other errors if the "Unsatisfiable" case wasn't triggered.
                # Could be added to expected errors later
                return any(is_unsatisfiable(err.exception_with_traceback) for err in ev.result.errors)
        return False

    def check_unsatisfiable(ev):
        # In some cases Schemathesis can't generate data - either due to a contradiction within the schema
        if schema_id in UNSATISFIABLE_SCHEMAS and ev.current_operation in UNSATISFIABLE_SCHEMAS[schema_id]:
            exception = ev.result.errors[0].exception
            if (
                "Unable to satisfy schema parameters for this API operation" not in exception
                and "Cannot create non-empty lists with elements" not in exception
                and "Cannot create a collection of " not in exception
            ):
                pytest.fail(f"Expected unsatisfiable, but there is a different error: {exception}")
            return True
        return False

    def check_recursive_references(ev):
        if schema_id in RECURSIVE_REFERENCES and ev.current_operation in RECURSIVE_REFERENCES[schema_id]:
            for err in ev.result.errors:
                if RECURSIVE_REFERENCE_ERROR_MESSAGE in err.exception_with_traceback:
                    # It is OK
                    return True
            # These errors may be triggered not every time
        return False

    def check_not_parsable(ev):
        return schema_id in NOT_PARSABLE_SCHEMAS and NOT_PARSABLE_SCHEMAS[schema_id] in ev.exception_with_traceback

    def check_invalid(ev):
        if schema_id in INVALID_SCHEMAS:
            if ev.result.errors:
                return any(
                    "The API schema contains non-string keys" in err.exception_with_traceback
                    for err in ev.result.errors
                )
            return pytest.fail("Expected YAML parsing error")
        return False

    for event in runner.execute():
        if isinstance(event, events.AfterExecution):
            if check_xfailed(event):
                continue
            if check_flaky(event):
                continue
            if check_recursive_references(event):
                continue
            if check_unsatisfiable(event):
                continue
            if check_invalid(event):
                continue
            assert not event.result.has_errors, event.current_operation
            assert not event.result.has_failures, event.current_operation
        if isinstance(event, events.InternalError):
            if check_not_parsable(event):
                continue
        assert not isinstance(event, events.InternalError), event.exception_with_traceback