I tagged v1.0.0 of go-schemathesis: a CLI that loads an OpenAPI 3.x document, generates HTTP cases from the schema, runs them against a live API, and checks the responses.
https://github.com/gonnafaraway/go-schemathesis
The approach is the one Schemathesis uses: the spec is the source of cases, not a hand-written fixture list. This build is a static Go binary (kin-openapi and cobra, no cgo). I wanted that check in a Go CI job without a Python environment.
A run has three phases:
- examples sends example / examples already written in the spec
- coverage walks declared bounds (minLength, maxLength, minimum, maximum, minItems, maxItems, enum, both booleans, omitted required body)
- fuzzing draws random cases from a seeded RNG (--seed replays the same draw)
- --mode is positive, negative, or all (the default). Six checks: 5xx, undocumented status, Content-Type, response schema, acceptance of valid data, rejection of invalid data. Each failure prints a shell-quoted curl.
go install github.com/gonnafaraway/go-schemathesis/cmd/schemathesis@latest
schemathesis run openapi.yaml --url http://127.0.0.1:8080 \
--phases examples,coverage \
--mode positive \
-H "Authorization: Bearer $TOKEN"
The v1.0.0 release has binaries for Linux, macOS, and Windows (amd64 and arm64) plus SHA256SUMS.
What a green run actually covers:
- OpenAPI 3.0 and 3.1. Swagger 2.0 is out.
- Response schema checks cover type, enum, required, properties, items, length and numeric bounds, and nullable. They do not cover pattern, format, additionalProperties, const, or allOf / anyOf / oneOf / not.
- Cases are independent. A created id is not reused on the next request. Real ids belong in spec examples; the tool does not read your database.
- Transport failures show up as Errors: and do not change the exit code. An unreachable host can exit 0. In CI, assert Errors: 0 on the summary line.
- Report is console text. No JUnit, JSON, or SARIF yet.
- The binary is named schemathesis. If the Python CLI is also on PATH, install this one to an explicit directory.
- negative and fuzzing send schema-violating input. Point them only at an API you are allowed to test, and confirm the target with --phases examples --mode positive first.
Useful feedback is a minimal spec where a check was wrong or stayed silent. The repo has a bug-report template; tokens should be redacted.
Same author, separate tools:
- go-arch-template — Go service skeleton: Clean Architecture, HTTP and gRPC, Postgres and Mongo, generated OpenAPI, Zap / OpenTelemetry / Prometheus.
- archgen — Markdown architecture notes, plus optional C4 files, generated from // archgen: comments in Go.
- kaiban — local Kanban where each column is an LLM role (product through QA). A card moves forward only after a person approves the column report.
Top comments (1)
oh nice, a curl per failure. Says the person who builds an API client and still debugs half his stuff with curl. Do you plan to chain created IDs, or keep cases independent on purpose? From my experience building Voiden, chaining is where we ended up with reusable requests in .void files in the repo, so a failing curl can turn into a regression step in the same PR: github.com/VoidenHQ/voiden (I work on it).