Documentation
¶
Overview ¶
Package gswag generates OpenAPI 3.0 specifications from Ginkgo integration tests.
Inspired by rswag (Ruby), gswag lets you write your API tests once and get a fully generated openapi.yaml for free — no annotations, no code generation.
Quick start ¶
- Call Init in your Ginkgo BeforeSuite with a Config.
- Call SetTestServer in BeforeSuite after starting your httptest.Server.
- Describe endpoints with the DSL: Path, Get, Post, Put, Patch, Delete.
- Declare parameters with Parameter, RequestBody and response schemas with ResponseSchema.
- Execute requests and assert with RunTest.
- Call WriteSpec in AfterSuite to emit the spec file.
Example:
var _ = BeforeSuite(func() {
gswag.Init(&gswag.Config{
Title: "My API",
Version: "1.0.0",
OutputPath: "./docs/openapi.yaml",
})
testServer = httptest.NewServer(myRouter)
gswag.SetTestServer(testServer)
})
var _ = AfterSuite(func() {
testServer.Close()
Expect(gswag.WriteSpec()).To(Succeed())
})
var _ = Path("/api/users/{id}", func() {
Get("Get user by ID", func() {
Tag("users")
Parameter("id", gswag.PathParam, gswag.String)
Response(200, "user found", func() {
ResponseSchema(new(User))
SetParam("id", "1")
RunTest(func(resp *http.Response) {
Expect(resp.StatusCode).To(Equal(200))
})
})
})
})
Index ¶
- Constants
- Variables
- func BearerAuth()
- func BeforeRequest(fn func())
- func Consumes(contentType string)
- func ContainJSONKey(key string) types.GomegaMatcher
- func Delete(summary string, fn func())
- func Deprecated()
- func Description(desc string)
- func Get(summary string, fn func())
- func HaveHeader(key, value string) types.GomegaMatcher
- func HaveJSONBody(expected any) types.GomegaMatcher
- func HaveNonEmptyBody() types.GomegaMatcher
- func HaveStatus(expected int) types.GomegaMatcher
- func HaveStatusInRange(lo, hi int) types.GomegaMatcher
- func Hidden()
- func Init(cfg *Config)
- func MatchJSONSchema(model any) types.GomegaMatcher
- func MergeAndWriteSpec(totalNodes int, dir string) error
- func OperationID(id string)
- func Parameter(name string, in ParamLocation, typ SchemaType, opts ...ParameterOption)
- func Patch(summary string, fn func())
- func Path(template string, fn func()) bool
- func Post(summary string, fn func())
- func Produces(contentTypes ...string)
- func Put(summary string, fn func())
- func QueryParamStruct(v any)
- func RegisterParallelSuiteHandlers(cfg *Config, partialDir string)
- func RegisterSuiteHandlers(cfg *Config)
- func RequestBody(model any)
- func Response(status int, description string, fn func())
- func ResponseHeader(name string, model any)
- func ResponseSchema(model any)
- func RunTest(fn ...func(*http.Response))
- func Security(schemeName string, scopes ...string)
- func SetBody(body any)
- func SetHeader(name, value string)
- func SetParam(name, value string)
- func SetQueryParam(name, value string)
- func SetRawBody(body []byte, contentType string)
- func SetTestServer(target any)
- func Tag(tags ...string)
- func WriteAndValidateSpec() error
- func WritePartialSpec(nodeIndex int, dir string) error
- func WriteSpec() error
- func WriteSpecTo(path string, format OutputFormat) error
- type Config
- type ContactConfig
- type ExternalDocsConfig
- type LicenseConfig
- type OutputFormat
- type ParamLocation
- type ParameterOption
- type SchemaType
- type SecuritySchemeConfig
- type ServerConfig
- type SpecCollector
- type TagConfig
- type TypeMapping
- type ValidationIssue
Constants ¶
const ( InPath ParamLocation = "path" InQuery ParamLocation = "query" InHeader ParamLocation = "header" InCookie ParamLocation = "cookie" // PathParam is a short alias for InPath. PathParam = InPath // QueryParam is a short alias for InQuery. QueryParam = InQuery // HeaderParam is a short alias for InHeader. HeaderParam = InHeader // CookieParam is a short alias for InCookie. CookieParam = InCookie )
Variables ¶
var ErrSpecInvalid = errors.New("spec has validation errors")
ErrSpecInvalid is returned when the spec has at least one error-level issue.
Functions ¶
func BearerAuth ¶
func BearerAuth()
BearerAuth adds a Bearer JWT security requirement to the current operation.
func BeforeRequest ¶
func BeforeRequest(fn func())
BeforeRequest registers a Ginkgo BeforeEach that runs before each RunTest It block inside the current operation or response. Use it to share SetParam, SetHeader, or SetBody calls across multiple Response blocks — similar to RSpec's let blocks in rswag.
Get("Get user", func() {
BeforeRequest(func() { SetParam("id", "42") })
Response(200, "found", func() { RunTest(...) })
Response(404, "missing", func() { RunTest(...) })
})
func Consumes ¶
func Consumes(contentType string)
Consumes sets the request body content-type for the current operation. Defaults to "application/json" when not called. Useful for multipart, form-encoded, or other non-JSON request bodies.
func ContainJSONKey ¶
func ContainJSONKey(key string) types.GomegaMatcher
ContainJSONKey succeeds when the response body is a JSON object containing the given key.
func Delete ¶
func Delete(summary string, fn func())
Delete declares a DELETE operation on the current path.
func Deprecated ¶
func Deprecated()
Deprecated marks the current operation as deprecated in the spec.
func Description ¶
func Description(desc string)
Description sets the description of the current operation.
func HaveHeader ¶
func HaveHeader(key, value string) types.GomegaMatcher
HaveHeader succeeds when the response contains the given header with the expected value.
func HaveJSONBody ¶
func HaveJSONBody(expected any) types.GomegaMatcher
HaveJSONBody succeeds when the response body can be JSON-decoded and equals expected after a round-trip JSON normalisation.
func HaveNonEmptyBody ¶
func HaveNonEmptyBody() types.GomegaMatcher
HaveNonEmptyBody succeeds when the response body is not empty.
func HaveStatus ¶
func HaveStatus(expected int) types.GomegaMatcher
HaveStatus succeeds when the response has the expected HTTP status code.
func HaveStatusInRange ¶
func HaveStatusInRange(lo, hi int) types.GomegaMatcher
HaveStatusInRange succeeds when the status code is in [lo, hi] inclusive.
func Hidden ¶
func Hidden()
Hidden excludes the current operation from the generated spec while still allowing RunTest to execute the underlying HTTP request.
func Init ¶
func Init(cfg *Config)
Init initialises gswag with the given configuration. Call this once in your Ginkgo BeforeSuite.
func MatchJSONSchema ¶
func MatchJSONSchema(model any) types.GomegaMatcher
MatchJSONSchema succeeds when every key present in the model type is also present in the response JSON (structural validation — values are not compared).
func MergeAndWriteSpec ¶
MergeAndWriteSpec reads all partial spec files written by WritePartialSpec, merges their paths and schemas, then writes the final spec using the global config. This must only be called on node 1 after all other nodes have called WritePartialSpec.
It polls for each node's partial file until it appears, using the MergeTimeout from the global config (default 30 s). Use Ginkgo's SynchronizedAfterSuite to guarantee all nodes have finished writing before this is called.
func OperationID ¶
func OperationID(id string)
OperationID sets the operationId of the current operation.
func Parameter ¶
func Parameter(name string, in ParamLocation, typ SchemaType, opts ...ParameterOption)
Parameter declares a named parameter for the current operation.
func Patch ¶
func Patch(summary string, fn func())
Patch declares a PATCH operation on the current path.
func Path ¶
Path wraps fn in a Ginkgo Describe node and pushes template onto the path stack. Use at package level with var _ = Path(...).
func Post ¶
func Post(summary string, fn func())
Post declares a POST operation on the current path.
func Produces ¶
func Produces(contentTypes ...string)
Produces sets the accepted response content-types for the current operation. Defaults to "application/json" when not called. Multiple content types may be specified to document endpoints that serve e.g. both JSON and XML.
func QueryParamStruct ¶
func QueryParamStruct(v any)
QueryParamStruct registers a struct with query tags as query parameter schemas.
func RegisterParallelSuiteHandlers ¶
RegisterParallelSuiteHandlers registers suite hooks suitable for parallel Ginkgo runs (`ginkgo -p`). Each node writes a partial spec; node 1 then merges them all into the final output.
partialDir is a temporary directory used to store per-node partial specs. It must be accessible by all parallel nodes (i.e. on a shared filesystem).
func TestAPI(t *testing.T) {
gswag.RegisterParallelSuiteHandlers(&gswag.Config{...}, "./tmp/gswag")
gomega.RegisterFailHandler(gomega.Fail)
ginkgo.RunSpecs(t, "API Suite")
}
func RegisterSuiteHandlers ¶
func RegisterSuiteHandlers(cfg *Config)
RegisterSuiteHandlers registers BeforeSuite and AfterSuite hooks that initialise gswag and write the spec on suite completion.
Call this from your TestXxx function or at package init, passing the same Config you would pass to Init. For parallel test runs use RegisterParallelSuiteHandlers instead.
func TestAPI(t *testing.T) {
gswag.RegisterSuiteHandlers(&gswag.Config{...})
gomega.RegisterFailHandler(gomega.Fail)
ginkgo.RunSpecs(t, "API Suite")
}
func RequestBody ¶
func RequestBody(model any)
RequestBody sets a typed struct as the request body schema for the current operation.
func Response ¶
Response declares a response for the current operation and wraps fn in a Ginkgo Context.
func ResponseHeader ¶
ResponseHeader declares a response header schema for the current response.
func ResponseSchema ¶
func ResponseSchema(model any)
ResponseSchema sets the expected response body schema model for the current response.
func RunTest ¶
RunTest registers a Ginkgo It block that fires the HTTP request and calls fn if provided.
func SetHeader ¶
func SetHeader(name, value string)
SetHeader sets a request header for the current test case.
func SetParam ¶
func SetParam(name, value string)
SetParam sets a path parameter value for the current test case.
func SetQueryParam ¶
func SetQueryParam(name, value string)
SetQueryParam sets a query parameter value for the current test case.
func SetRawBody ¶
SetRawBody sets a raw request body for the current test case.
func SetTestServer ¶
func SetTestServer(target any)
SetTestServer registers the HTTP target used by RunTest.
func WriteAndValidateSpec ¶
func WriteAndValidateSpec() error
WriteAndValidateSpec writes the spec and then validates it. Returns ErrSpecInvalid (wrapping the issue list) if any errors are found.
func WritePartialSpec ¶
WritePartialSpec serialises the current collector's spec to a file inside dir. The file is named after nodeIndex (1-based) so that the merge step can discover all node outputs without coordination.
Call this in AfterSuite on every parallel Ginkgo node before shutting down:
var _ = AfterSuite(func() {
testServer.Close()
Expect(gswag.WritePartialSpec(GinkgoParallelProcess(), "./tmp/gswag")).To(Succeed())
if GinkgoParallelProcess() == 1 {
Expect(gswag.MergeAndWriteSpec(GinkgoProcs(), "./tmp/gswag")).To(Succeed())
}
})
func WriteSpec ¶
func WriteSpec() error
WriteSpec serialises the collected spec to the path and format configured via Init.
func WriteSpecTo ¶
func WriteSpecTo(path string, format OutputFormat) error
WriteSpecTo serialises the collected spec to a specific path and format.
Types ¶
type Config ¶
type Config struct {
Title string
Version string
Description string
TermsOfService string
Contact *ContactConfig
License *LicenseConfig
ExternalDocs *ExternalDocsConfig
Tags []TagConfig
OutputPath string // default: "./docs/openapi.yaml"
OutputFormat OutputFormat
Servers []ServerConfig
// ExcludePaths omits matching operations from the generated spec.
// Entries support exact path matches and simple prefix patterns ending in '*'.
ExcludePaths []string
SecuritySchemes map[string]SecuritySchemeConfig
// EnforceResponseValidation enables test-time validation of actual HTTP
// responses against the declared or inferred response schema. When true,
// validation behavior is controlled by ValidationMode.
EnforceResponseValidation bool
// ValidationMode controls runtime behavior when a validation error occurs.
// Allowed values: "fail" (default) — cause test to fail/panic; "warn" —
// write a warning to stderr and continue.
ValidationMode string
// CaptureExamples enables storing request and response bodies as examples
// in the generated spec. When true, request/response bodies observed at
// test time are attached to the OpenAPI `examples` or `example` fields.
CaptureExamples bool
// MaxExampleBytes caps the number of bytes stored for any single example.
// A value of 0 means no cap. Defaults to 16384 (16 KiB) when zero.
MaxExampleBytes int
// Sanitizer is an optional hook to transform or redact example bytes before
// they are stored in the spec. If nil, examples are recorded verbatim (subject to cap).
Sanitizer func([]byte) []byte
// StripDefinitionNamePrefixes lists definition name prefixes that should be
// removed from reflected JSON Schema definition names. Applied when building
// reflectors so component schema names are cleaner.
StripDefinitionNamePrefixes []string
// InlineRefs controls whether JSON Schema reflector inlines referenced
// types instead of creating component references. When true, schemas
// are attempted to be inlined where possible.
InlineRefs bool
// TypeMappings holds list of type substitutions to apply to the jsonschema
// reflector. Each mapping calls `AddTypeMapping(src, dst)`.
TypeMappings []TypeMapping
// MergeTimeout is the maximum duration MergeAndWriteSpec will wait for each
// parallel node's partial spec file to appear. Defaults to 30 s when zero.
MergeTimeout time.Duration
}
Config holds global settings for gswag.
type ContactConfig ¶
ContactConfig describes OpenAPI info.contact metadata.
type ExternalDocsConfig ¶
ExternalDocsConfig describes OpenAPI external documentation metadata.
type LicenseConfig ¶
LicenseConfig describes OpenAPI info.license metadata.
type OutputFormat ¶
type OutputFormat int
OutputFormat controls the serialization format of the generated spec.
const ( YAML OutputFormat = iota JSON )
type ParamLocation ¶
type ParamLocation string
ParamLocation indicates where a parameter appears in an HTTP request.
type ParameterOption ¶
type ParameterOption func(*dslParam)
ParameterOption customizes an operation parameter declared by Parameter.
func ParamDefault ¶
func ParamDefault(value any) ParameterOption
ParamDefault sets the parameter default value in the generated schema.
func ParamEnum ¶
func ParamEnum(values ...any) ParameterOption
ParamEnum constrains parameter values to the provided enum values.
func ParamExplode ¶
func ParamExplode(explode bool) ParameterOption
ParamExplode controls the OpenAPI explode flag for the parameter.
func ParamRequired ¶
func ParamRequired(required bool) ParameterOption
ParamRequired marks a parameter as required/optional in the generated spec.
type SchemaType ¶
type SchemaType string
SchemaType is the OpenAPI primitive type for a declared parameter or schema.
const ( String SchemaType = "string" Integer SchemaType = "integer" Number SchemaType = "number" Boolean SchemaType = "boolean" Object SchemaType = "object" Array SchemaType = "array" )
type SecuritySchemeConfig ¶
type SecuritySchemeConfig struct {
Type string // "http", "apiKey", "oauth2", "openIdConnect"
Scheme string // e.g. "bearer"
BearerFormat string // e.g. "JWT"
In string // "header", "query", "cookie" (apiKey)
Name string // header/query/cookie parameter name (apiKey)
// OAuth2 implicit flow fields.
AuthorizationURL string // e.g. https://petstore3.swagger.io/oauth/authorize
RefreshURL string // optional refresh URL
Scopes map[string]string // scope -> description
}
SecuritySchemeConfig describes a named security scheme.
func APIKeyCookie ¶
func APIKeyCookie(cookieName string) SecuritySchemeConfig
APIKeyCookie returns a SecuritySchemeConfig for an API key passed in a cookie.
func APIKeyHeader ¶
func APIKeyHeader(headerName string) SecuritySchemeConfig
APIKeyHeader returns a SecuritySchemeConfig for an API key passed in a header.
func APIKeyQuery ¶
func APIKeyQuery(paramName string) SecuritySchemeConfig
APIKeyQuery returns a SecuritySchemeConfig for an API key passed in a query param.
func BearerJWT ¶
func BearerJWT() SecuritySchemeConfig
BearerJWT returns a SecuritySchemeConfig for an HTTP Bearer JWT scheme.
func OAuth2Implicit ¶
func OAuth2Implicit(authURL string, scopes map[string]string) SecuritySchemeConfig
OAuth2Implicit returns a SecuritySchemeConfig for an OAuth2 implicit flow.
type ServerConfig ¶
ServerConfig describes an OpenAPI server entry.
type SpecCollector ¶
type SpecCollector struct {
// contains filtered or unexported fields
}
SpecCollector accumulates OpenAPI operations from test executions in a thread-safe manner.
func (*SpecCollector) Register ¶
func (sc *SpecCollector) Register(b *requestBuilder, res *recordedResponse)
Register adds an operation to the spec based on the requestBuilder metadata and the actual recordedResponse. Safe to call concurrently.
func (*SpecCollector) RegisterDSLOperation ¶
func (sc *SpecCollector) RegisterDSLOperation(op *dslOp)
RegisterDSLOperation registers an operation declared via the rswag-style DSL. Called from a Ginkgo BeforeAll node so that spec registration happens once per operation, before any RunTest It blocks execute.
type TagConfig ¶
type TagConfig struct {
Name string
Description string
ExternalDocs *ExternalDocsConfig
}
TagConfig describes a top-level OpenAPI tag with optional metadata.
type TypeMapping ¶
TypeMapping describes a substitution between two Go types for JSON Schema reflection. Provide a sample `Src` value (or a type) and a `Dst` value to map to.
type ValidationIssue ¶
type ValidationIssue struct {
Severity string // "error" or "warning"
Path string // e.g. "paths./users.get"
Message string
}
ValidationIssue describes a single spec problem.
func ValidateSpec ¶
func ValidateSpec() []ValidationIssue
ValidateSpec runs structural validation on the collected spec and returns any issues found. Errors must be fixed for a valid spec; warnings are informational.
func ValidateSpecFile ¶
func ValidateSpecFile(path string) ([]ValidationIssue, error)
ValidateSpecFile reads a YAML or JSON spec file and runs structural validation.
func (ValidationIssue) String ¶
func (v ValidationIssue) String() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
golden
Package golden provides helpers for golden-file based testing.
|
Package golden provides helpers for golden-file based testing. |
|
schemautil
Package schemautil provides best-effort JSON → OpenAPI schema inference.
|
Package schemautil provides best-effort JSON → OpenAPI schema inference. |
|
test
|
|