Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SpecSmash

Property-based testing for OpenAPI 3.0 specifications in Go

Ever wanted to destroy your validator? Were you too lazy to write proper unit tests for your validation?

Say No More

SpecSmash generates random test data that conforms to your OpenAPI 3.0 schemas. Inspired by hypothesis-jsonschema but for Go.

Features

  • Automatic Test Data Generation - Generates realistic test data from OpenAPI 3.0 schemas
  • Schema Validation - Ensures generated data validates against your spec
  • Property-Based Testing - Leverages pgregory.net/rapid for exhaustive edge case discovery
  • Comprehensive Coverage - Supports complex schemas including:
    • All primitive types (string, number, integer, boolean)
    • String formats (uuid, date-time, email, byte, etc.)
    • Objects with nested properties
    • Arrays with various item types
    • oneOf, anyOf, allOf compositions
    • Nullable fields
    • Min/max constraints, enums
    • Additional properties
  • Custom Pattern Generators - Provide your own pattern matching functions for regex patterns and string formats

Installation

go get github.com/djosh34/specsmash

Quick Start

package main

import (
    "testing"
    "github.com/djosh34/specsmash"
    "pgregory.net/rapid"
)

func TestMyAPI(t *testing.T) {
    // Load your OpenAPI spec
    spec, err := SpecSmash.ReadSpec("testdata/openapi.yaml")
    if err != nil {
        t.Fatal(err)
    }

    // Generate and validate test data
    rapid.Check(t, func(t *rapid.T) {
        // Get the schema you want to test
        schema := spec.Components.Schemas["User"].Value
        
        // Generate data conforming to the schema
        generator := SpecSmash.GenFromSchema(schema)
        data := generator.Draw(t, "user-data")
        
        // Use the generated data to test your API
        // ... your test logic here
    })
}

Pattern Matching

SpecSmash requires you to provide a custom pattern function for schemas that use pattern constraints or certain string formats (email, hostname, ipv4, ipv6, uri, uri-reference). This is because ECMA regex patterns are not natively supported.

Using Pattern Functions

import (
    "testing"
    "github.com/djosh34/specsmash"
    "pgregory.net/rapid"
)

func TestWithPatterns(t *testing.T) {
    spec, err := SpecSmash.ReadSpec("testdata/openapi.yaml")
    if err != nil {
        t.Fatal(err)
    }

    // Create generation options with a custom pattern function
    opts := SpecSmash.NewGenerationOptions().WithPatternFunc(
        func(pattern string, format string, minLength int, maxLength int, t *rapid.T) string {
            // Use rapid.StringMatching or your own implementation
            // NOTE: rapid.StringMatching uses RE2 syntax, not ECMA
            return rapid.StringMatching(pattern).Draw(t, "pattern-"+format)
        },
    )

    rapid.Check(t, func(t *rapid.T) {
        schema := spec.Components.Schemas["User"].Value
        
        // Use the custom options
        generator := opts.GenFromSchema(schema)
        data := generator.Draw(t, "user-data")
        
        // ... your test logic here
    })
}

The pattern function receives:

  • pattern - The regex pattern from the schema (or a suggested pattern for formats)
  • format - The string format (e.g., "email", "ipv4", or empty string for custom patterns)
  • minLength - Minimum string length constraint from the schema
  • maxLength - Maximum string length constraint from the schema (-1 if not set)
  • t - The rapid.T instance for drawing values

Important: If your schema contains patterns or certain string formats and you don't provide a PatternFunc, the generator will panic with a helpful error message.

Limitations

  • multipleOf is not fully supported due to implementation errors (in this version). It will generate valid multipleOfs most of the time, unless you have very small multipliers that will cause precision issues
  • anyOf when both have a shared property, the generator will error (in this version)
  • Pattern matching requires a user-provided function due to ECMA regex incompatibility

How It Works

SpecSmash uses kin-openapi to parse OpenAPI specifications and rapid for property-based test generation. It intelligently creates generators that respect all schema constraints including types, formats, ranges, patterns, and compositions.

License

MIT

About

Property-based testing for OpenAPI 3.0 specifications in Go. Generate random test data that conforms to your OpenAPI schemas.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages