High-level overview of the execution path of Schemathesis, which is not easy to piece together and not well-documented.
- Runner class runs
_run_tests()withmaker=schema.get_all_testsandtemplate=network_test _run_testsrunsmaker(which isschema.get_all_tests) withfunc=network_test- Schema
get_all_teststakes every API operation and callscreate_testwith operation andtest=func=network_test create_test:- turns operation into a Hypothesis data generation strategy by calling
operation.as_strategy - Wraps the
test=network_testfunction in ahypothesis.givenannotation withcase=strategyas kwarg
- turns operation into a Hypothesis data generation strategy by calling
_run_testsreceives the Hypothesis test fromcreate_testand callsrun_teston the hypothesis testrun_testruns the hypothesis test (which wrapsnetwork_test) and extracts some data from itnetwork_testis called by Hypothesis with thecaseargument populated by Hypothesis given (???) using the strategy defined increate_testnetwork_testcalls_network_testwhich- calls
case.call()which sends the HTTP request - checks the response against the defined checks
- calls
operation.as_strategycallsschema.get_case_strategy(operation)and then applies hooks to it.- This forwards to the actual method, which generates the actual case.
- Calls generate_parameter for path params, headers, cookies, and query params through
generate_parameter - Fills in the body by selecting a schema for the body and passing it to
_get_body_strategythen applying hooks to the strategy
- Calls generate_parameter for path params, headers, cookies, and query params through
_get_body_strategyprepares the jsonschema and calls thestrategy_factorypassed to it, which is usuallymake_positive_strategy. It also adds the case of not-set if the body is optional.make_positive_strategydefers tohypothesis_jsonschema.from_schema
Seemingly based purely on OpenAPI links, and mostly undocumented. Not useful for Onweer, as links are not often specified.
Method which turns an APIOperation into a strategy producing Case that can be executed.
Any parameters which are filled in in the APIOperation object will be kept and supplemented with randomly generated inputs where necessary.
Except for the body, which if it is filled in will be used exactly as it is. It is not supplemented.
- Major limitation, would be nice to resolve but not urgent (request bodies are not too essential, hopefully)
APIOperation is generic in the type of the parameters so it can be reused between openapi and graphql.
Current working theory: the concrete type of the P parameter is either OpenAPIParameter or its child class OpenAPI30Parameter (or the same with openapi 2.0 but we’re not using that). The differences between these two don’t seem to matter too much, so we can just work on OpenAPIParameter if this is the correct class.
This parameter class seems to have a relatively comprehensive and usable interface, should be useful for matching data dependencies. Need to look at how RESTler and WuppieFuzz do this matching.