What is Schemathesis?
Schemathesis is an open-source, MIT-licensed tool that tests an API by generating requests from its OpenAPI or GraphQL schema. It is built on Hypothesis, the Python property-based testing library, so instead of running the handful of cases someone wrote by hand, it derives valid and deliberately invalid inputs from the schema, sends them to a running API, and checks each response against what the schema promises. It runs as a CLI (st run), as a pytest plugin, and as a GitHub Action, and it supports OpenAPI 2.0 through 3.2.
Why use it in the API Lifecycle?
- Finds the cases nobody wrote: Generated inputs hit boundary values, unusual strings and missing fields that hand-written tests rarely cover, which is where
500 Internal Server Errorresponses hide. - Checks the spec against the implementation: Built-in checks include
not_a_server_error,status_code_conformance,content_type_conformance,response_headers_conformanceandresponse_schema_conformance, so undocumented status codes and responses that drift from the schema fail the run. - Negative testing:
negative_data_rejectionasserts that invalid input gets an error status rather than being accepted, andpositive_data_acceptanceasserts the reverse for valid input. Both accept a configurableexpected-statuseslist.--mode positive|negative|allcontrols which is generated. - Stateful testing: The
statefulphase chains operations into workflows (create, then read, then delete) using OpenAPI links or links it infers from the schema, and checks such asuse_after_freeandensure_resource_availabilitycatch resources that survive deletion or vanish after creation. - Authorization checks:
ignored_authflags operations that answer without the credentials the schema requires, andobject_level_authorizationprobes for one caller reading another’s resources. - CI-ready output: Reports in JUnit, HAR, VCR, NDJSON, Allure and HTML formats, with failures reproducible as plain
curlcommands.
Best Practices
- Run it against a disposable or staging environment, never production. It sends real create, update and delete requests with hostile data, and it will find the ones that work.
- Start with
uvx schemathesis run ./openapi.yaml --url http://localhost:8000locally, then add the GitHub Action to every pull request so a schema change and its implementation are tested together. The wider testing strategy is in API Testing. - Fix the schema, not just the code. A large share of first-run failures are an OpenAPI document that omits a
404 Not Foundor a422 Unprocessable Contentthe API really returns; documenting it is the correct fix. - Pass credentials with
-H 'Authorization: Bearer ...'or the auth configuration inschemathesis.toml, and run once without them to confirm unauthenticated calls get401 Unauthorized. - Keep
-n(--max-examples) modest on every pull request and raise it in a nightly job. Use--report junitso failures show up in the CI test view rather than in a log nobody reads. - Treat a
not_a_server_errorfailure as a bug every time. A malformed request should produce a 4xx with a problem details body, never a stack trace.