Beispiel #1
0
def test_execute_filter_method(args):
    app, kwargs = args
    # When `method` passed in `loader_options` corresponds to a method that is not defined in the app schema
    kwargs.setdefault("loader_options", {})["method"] = ["POST"]
    execute(**kwargs)
    # Then runner will not make any requests
    assert_incoming_requests_num(app, 0)
Beispiel #2
0
def test_hypothesis_deadline(schema_url, app):
    # When `deadline` is passed in `hypothesis_options` in the `execute` call
    execute(schema_url, hypothesis_options={"deadline": 500})

    # Then it should be passed to `hypothesis.settings`
    # And slow endpoint (250ms) should not be considered as breaking the deadline
    assert len(app["incoming_requests"]) == 1
    assert_request(app, 0, "GET", "/api/slow")
Beispiel #3
0
def test_execute_filter_endpoint(schema_url, app):
    # When `endpoint` is passed in `loader_options` in the `execute` call
    execute(schema_url, loader_options={"endpoint": ["success"]})

    # Then the runner will make calls only to the specified endpoint
    assert len(app["incoming_requests"]) == 1
    assert_request(app, 0, "GET", "/api/success")
    assert_not_request(app, "GET", "/api/failure")
Beispiel #4
0
def test_execute_filter_endpoint(args):
    app, kwargs = args
    # When `endpoint` is passed in `loader_options` in the `execute` call
    kwargs.setdefault("loader_options", {})["endpoint"] = ["success"]
    execute(**kwargs)

    # Then the runner will make calls only to the specified endpoint
    assert_incoming_requests_num(app, 1)
    assert_request(app, 0, "GET", "/api/success")
    assert_not_request(app, "GET", "/api/failure")
Beispiel #5
0
def test_auth(schema_url, app):
    # When auth is specified in `api_options` as a tuple of 2 strings
    execute(schema_url, api_options={"auth": ("test", "test")})

    # Then each request should contain corresponding basic auth header
    assert len(app["incoming_requests"]) == 3
    headers = {"Authorization": "Basic dGVzdDp0ZXN0"}
    assert_request(app, 0, "GET", "/api/failure", headers)
    assert_request(app, 1, "GET", "/api/failure", headers)
    assert_request(app, 2, "GET", "/api/success", headers)
Beispiel #6
0
def test_execute_with_headers(schema_url, app):
    # When headers are specified for the `execute` call
    headers = {"Authorization": "Bearer 123"}
    execute(schema_url, api_options={"headers": headers})

    # Then each request should contain these headers
    assert len(app["incoming_requests"]) == 3
    assert_request(app, 0, "GET", "/api/failure", headers)
    assert_request(app, 1, "GET", "/api/failure", headers)
    assert_request(app, 2, "GET", "/api/success", headers)
Beispiel #7
0
def test_base_url(base_url, schema_url, app, converter):
    base_url = converter(base_url)
    # When `base_url` is specified explicitly with or without trailing slash
    execute(schema_url, loader_options={"base_url": base_url})

    # Then each request should reach the app in both cases
    assert_incoming_requests_num(app, 3)
    assert_request(app, 0, "GET", "/api/failure")
    assert_request(app, 1, "GET", "/api/failure")
    assert_request(app, 2, "GET", "/api/success")
Beispiel #8
0
def test_auth(args):
    app, kwargs = args
    # When auth is specified in `api_options` as a tuple of 2 strings
    execute(**kwargs, api_options={"auth": ("test", "test")})

    # Then each request should contain corresponding basic auth header
    assert_incoming_requests_num(app, 3)
    headers = {"Authorization": "Basic dGVzdDp0ZXN0"}
    assert_request(app, 0, "GET", "/api/failure", headers)
    assert_request(app, 1, "GET", "/api/failure", headers)
    assert_request(app, 2, "GET", "/api/success", headers)
Beispiel #9
0
def test_execute_with_headers(args):
    app, kwargs = args
    # When headers are specified for the `execute` call
    headers = {"Authorization": "Bearer 123"}
    execute(**kwargs, api_options={"headers": headers})

    # Then each request should contain these headers
    assert_incoming_requests_num(app, 3)
    assert_request(app, 0, "GET", "/api/failure", headers)
    assert_request(app, 1, "GET", "/api/failure", headers)
    assert_request(app, 2, "GET", "/api/success", headers)
Beispiel #10
0
def test_flaky_exceptions(args, mocker):
    app, kwargs = args
    # GH: #236
    error_idx = 0

    def flaky(*args, **kwargs):
        nonlocal error_idx
        exception_class = [ValueError, TypeError, ZeroDivisionError,
                           KeyError][error_idx % 4]
        error_idx += 1
        raise exception_class

    # When there are many different exceptions during the test
    # And Hypothesis consider this test as a flaky one
    mocker.patch("schemathesis.Case.call", side_effect=flaky)
    mocker.patch("schemathesis.Case.call_wsgi", side_effect=flaky)
    results = execute(**kwargs,
                      hypothesis_options={
                          "max_examples": 3,
                          "derandomize": True
                      })
    # Then the execution result should indicate errors
    assert results.has_errors
    assert results.results[0].errors[0][0].args[0].startswith(
        "Tests on this endpoint produce unreliable results:")
Beispiel #11
0
def test_invalid_path_parameter(args):
    app, kwargs = args
    results = execute(**kwargs)
    assert results.has_errors
    error, _ = results.results[0].errors[0]
    assert isinstance(error, InvalidSchema)
    assert str(error) == "Missing required property `required: true`"
def test_known_content_type(args):
    app, kwargs = args
    # When endpoint returns a response with a proper content type
    # And "content_type_conformance" is specified
    results = execute(**kwargs, checks=(content_type_conformance,), hypothesis_options={"max_examples": 1})
    # Then there should be no a failures
    assert not results.has_failures
Beispiel #13
0
def test_execute(args):
    app, kwargs = args
    # When the runner is executed against the default test app
    stats = execute(**kwargs)

    # Then there are three executed cases
    # Two errors - the second one is a flakiness check
    headers = {"User-Agent": f"schemathesis/{__version__}"}
    assert_schema_requests_num(app, 1)
    schema_requests = get_schema_requests(app)
    assert schema_requests[0].headers.get(
        "User-Agent") == headers["User-Agent"]
    assert_incoming_requests_num(app, 3)
    assert_request(app, 0, "GET", "/api/failure", headers)
    assert_request(app, 1, "GET", "/api/failure", headers)
    assert_request(app, 2, "GET", "/api/success", headers)

    # And statistic is showing the breakdown of cases types
    assert stats.total == {
        "not_a_server_error": {
            Status.success: 1,
            Status.failure: 2,
            "total": 3
        }
    }
Beispiel #14
0
def test_form_data(args):
    app, kwargs = args

    def is_ok(response, result):
        assert response.status_code == 200

    def check_content(response, result):
        if isinstance(app, Flask):
            data = response.json
        else:
            data = response.json()
        assert isinstance(data["key"], str)
        assert data["value"].lstrip("-").isdigit()

    # When endpoint specifies parameters with `in=formData`
    # Then responses should have 200 status, and not 415 (unsupported media type)
    results = execute(**kwargs,
                      checks=(is_ok, check_content),
                      hypothesis_options={"max_examples": 3})
    # And there should be no errors or failures
    assert not results.has_errors
    assert not results.has_failures
    # And the application should receive 3 requests as specified in `max_examples`
    assert_incoming_requests_num(app, 3)
    # And the Content-Type of incoming requests should be `multipart/form-data`
    incoming_requests = get_incoming_requests(app)
    assert incoming_requests[0].headers["Content-Type"].startswith(
        "multipart/form-data")
def test_response_conformance_valid(args):
    app, kwargs = args
    # When endpoint returns a response that conforms to the schema
    # And "response_schema_conformance" is specified
    results = execute(**kwargs, checks=(response_schema_conformance,), hypothesis_options={"max_examples": 1})
    # Then there should be no failures or errors
    assert not results.has_failures
    assert not results.has_errors
def test_response_conformance_text(args):
    app, kwargs = args
    # When endpoint returns a response that is not JSON
    # And "response_schema_conformance" is specified
    results = execute(**kwargs, checks=(response_schema_conformance,), hypothesis_options={"max_examples": 1})
    # Then the check should be ignored if the response headers are not application/json
    assert not results.has_failures
    assert not results.has_errors
def test_path_parameters_encoding(schema_url):
    # NOTE. Flask still decodes %2F as / and returns 404
    # When endpoint has a path parameter
    results = execute(schema_url, checks=(status_code_conformance,), hypothesis_options={"derandomize": True})
    # Then there should be no failures
    # since all path parameters are quoted
    assert not results.has_errors
    assert not results.has_failures
def test_response_conformance_malformed_json(args):
    app, kwargs = args
    # When endpoint returns a response that contains a malformed JSON, but has a valid content type header
    # And "response_schema_conformance" is specified
    results = execute(**kwargs, checks=(response_schema_conformance,), hypothesis_options={"max_examples": 1})
    # Then there should be a failure
    assert results.has_errors
    error = results.results[-1].errors[-1][0]
    assert "Expecting property name enclosed in double quotes" in str(error)
def test_unknown_content_type(args):
    app, kwargs = args
    # When endpoint returns a response with content type, not specified in "produces"
    # And "content_type_conformance" is specified
    results = execute(**kwargs, checks=(content_type_conformance,), hypothesis_options={"max_examples": 1})
    # Then there should be a failure
    assert results.has_failures
    check = results.results[0].checks[0]
    assert check.name == "content_type_conformance"
    assert check.value == Status.failure
def test_unknown_response_code_with_default(args):
    app, kwargs = args
    # When endpoint returns a status code, that is not listed in "responses", but there is a "default" response
    # And "status_code_conformance" is specified
    results = execute(**kwargs, checks=(status_code_conformance,), hypothesis_options={"max_examples": 1})
    # Then there should be no failure
    assert not results.has_failures
    check = results.results[0].checks[0]
    assert check.name == "status_code_conformance"
    assert check.value == Status.success
def test_response_conformance_invalid(args):
    app, kwargs = args
    # When endpoint returns a response that doesn't conform to the schema
    # And "response_schema_conformance" is specified
    results = execute(**kwargs, checks=(response_schema_conformance,), hypothesis_options={"max_examples": 1})
    # Then there should be a failure
    assert results.has_failures
    lines = results.results[0].checks[-1].message.split("\n")
    assert lines[0] == "The received response does not conform to the defined schema!"
    assert lines[2] == "Details: "
    assert lines[4] == "'success' is a required property"
Beispiel #22
0
def test_unknown_response_code(schema_url, app):
    # When endpoint returns a status code, that is not listed in "responses"
    # And "status_code_conformance" is specified
    results = execute(schema_url,
                      checks=(status_code_conformance, ),
                      hypothesis_options={"max_examples": 1})
    # Then there should be a failure
    assert results.has_failures
    check = results.results[0].checks[0]
    assert check.name == "status_code_conformance"
    assert check.value == Status.failure
async def test_payload_explicit_example(args):
    # When endpoint has an example specified
    app, kwargs = args
    kwargs.setdefault("hypothesis_options", {})["phases"] = [Phase.explicit]
    result = execute(**kwargs)
    # Then run should be successful
    assert not result.has_errors
    assert not result.has_failures
    incoming_requests = get_incoming_requests(app)

    if isinstance(app, Flask):
        body = incoming_requests[0].json
    else:
        body = await incoming_requests[0].json()
    # And this example should be sent to the app
    assert body == {"name": "John"}
Beispiel #24
0
def test_execute(schema_url, app):
    # When the runner is executed against the default test app
    stats = execute(schema_url)

    # Then there are three executed cases
    # Two errors - the second one is a flakiness check
    headers = {"User-Agent": f"schemathesis/{__version__}"}
    assert len(app["incoming_requests"]) == 3
    assert_request(app, 0, "GET", "/api/failure", headers)
    assert_request(app, 1, "GET", "/api/failure", headers)
    assert_request(app, 2, "GET", "/api/success", headers)

    # And statistic is showing the breakdown of cases types
    assert "not_a_server_error" in stats.data
    assert dict(stats.data["not_a_server_error"]) == {
        "total": 3,
        "ok": 1,
        "error": 2
    }
Beispiel #25
0
def test_execute_base_url_found(base_url, schema_url, app):
    # When base_url is specified
    execute(schema_url, loader_options={"base_url": base_url})
    # Then it should be used by the runner
    assert_incoming_requests_num(app, 3)
Beispiel #26
0
def test_execute_base_url_not_found(base_url, schema_url, app):
    # When base URL is pointing to an unknown location
    execute(schema_url, loader_options={"base_url": f"{base_url}/404/"})
    # Then the runner should use this base
    # And they will not reach the application
    assert_incoming_requests_num(app, 0)
Beispiel #27
0
def test_hypothesis_deadline(schema_url, app):
    # When `deadline` is passed in `hypothesis_options` in the `execute` call
    execute(schema_url, hypothesis_options={"deadline": 500})
Beispiel #28
0
def test_hypothesis_deadline(args):
    app, kwargs = args
    # When `deadline` is passed in `hypothesis_options` in the `execute` call
    execute(**kwargs, hypothesis_options={"deadline": 500})
    assert_incoming_requests_num(app, 1)
    assert_request(app, 0, "GET", "/api/slow")
Beispiel #29
0
def test_execute_base_url_found(base_url, schema_url, app):
    # When base_url is specified
    execute(schema_url, api_options={"base_url": base_url})
    # Then it should be used by the runner
    assert len(app["incoming_requests"]) == 3
Beispiel #30
0
def test_execute_filter_method(schema_url, app):
    # When `method` passed in `loader_options` corresponds to a method that is not defined in the app schema
    execute(schema_url, loader_options={"method": ["POST"]})
    # Then runner will not make any requests
    assert len(app["incoming_requests"]) == 0