Project

miniswag

0.0
No release in over 3 years
Write API integration tests in Minitest that simultaneously validate your API and generate OpenAPI 3.x specification files. Compatible with rswag-api and rswag-ui for serving docs and Swagger UI.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 7.0, < 9.0
>= 7.0, < 9.0
>= 2.2, < 7.0
~> 5.0
>= 7.0, < 9.0
 Project Readme

Miniswag

OpenAPI (Swagger) documentation DSL for Minitest. A port of rswag that works with Minitest instead of RSpec.

Write API integration tests that simultaneously validate your API responses and generate OpenAPI 3.x specification files — no RSpec required.

Gems

Gem Description
miniswag Core DSL and OpenAPI spec generator (replaces rswag-specs)
miniswag-api Rails engine that serves OpenAPI files as JSON/YAML endpoints (replaces rswag-api)
miniswag-ui Rails engine that serves Swagger UI powered by your OpenAPI specs (replaces rswag-ui)

Installation

Add to your Gemfile:

# Core — test DSL + spec generation
gem "miniswag", group: :test

# Optional — serve specs and Swagger UI in your app
gem "miniswag-api"
gem "miniswag-ui"

Then run:

bundle install
rails generate miniswag:install        # creates test/openapi_helper.rb
rails generate miniswag:api:install    # creates config/initializers/miniswag_api.rb
rails generate miniswag:ui:install     # creates config/initializers/miniswag_ui.rb

Quick Start

1. Configure your OpenAPI specs

Edit test/openapi_helper.rb:

require "miniswag"

Miniswag.configure do |config|
  config.openapi_root = Rails.root.join("docs/api").to_s

  config.openapi_specs = {
    "v1.yaml" => {
      openapi: "3.0.1",
      info: { title: "My API", version: "v1" },
      servers: [{ url: "https://api.example.com" }]
    }
  }
end

2. Write a test

require "openapi_helper"

class PetsTest < Miniswag::TestCase
  path "/pets" do
    get "Lists all pets" do
      tags "Pets"
      produces "application/json"

      response 200, "successful" do
        schema type: :array, items: { "$ref" => "#/components/schemas/Pet" }

        run_test!
      end
    end

    post "Creates a pet" do
      tags "Pets"
      consumes "application/json"
      parameter name: :body, in: :body, schema: {
        type: :object,
        properties: {
          name: { type: :string },
          age: { type: :integer }
        },
        required: %w[name]
      }

      response 201, "pet created" do
        params { { body: { name: "Fido", age: 3 } } }

        run_test!
      end

      response 422, "invalid request" do
        params { { body: { age: -1 } } }

        run_test!
      end
    end
  end
end

3. Generate OpenAPI specs

rake miniswag:swaggerize

This runs your tests and writes the resulting OpenAPI files to openapi_root.

DSL Reference

The DSL mirrors rswag closely. Key differences from rswag are noted below.

Structure

class MyTest < Miniswag::TestCase
  openapi_spec "admin.yaml"          # target a specific spec file

  path "/resources/{id}" do
    get "Fetch a resource" do
      response 200, "success" do
        run_test!
      end
    end
  end
end

Parameters

parameter name: :id, in: :path, type: :integer
parameter name: :status, in: :query, type: :string
parameter name: "X-Request-Id", in: :header, type: :string
parameter name: :body, in: :body, schema: { type: :object, properties: { ... } }

Path parameters are automatically marked required: true.

Providing parameter values

Instead of rswag's let blocks, use params:

response 200, "success" do
  params { { id: @resource.id, status: "active" } }
  run_test!
end

Setup (replacing let! / before)

response 200, "success" do
  before { @resource = create_resource(name: "test") }
  params { { id: @resource.id } }
  run_test!
end

Custom assertions after the request

run_test! do |response|
  data = JSON.parse(response.body)
  assert_equal "test", data["name"]
end

Operation attributes

get "Fetch resource" do
  tags "Resources"
  operationId "getResource"
  description "Returns a single resource by ID"
  consumes "application/json"
  produces "application/json"
  security [{ bearer: [] }]
  deprecated true
end

Response schema & headers

response 200, "success" do
  schema type: :object, properties: { id: { type: :integer } }
  header "X-Rate-Limit", type: :integer, description: "Requests per hour"
  run_test!
end

Request body examples

post "Create resource" do
  request_body_example value: { name: "example" }, summary: "Basic example"
  # ...
end

Metadata (custom extensions)

response 200, "success" do
  metadata[:operation] ||= {}
  metadata[:operation]["x-public-docs"] = true
  run_test!
end

Migrating from rswag

rswag (RSpec) miniswag (Minitest)
RSpec.describe "...", type: :request do class MyTest < Miniswag::TestCase
let(:Authorization) { "Bearer ..." } params { { Authorization: "Bearer ..." } }
let!(:resource) { create(:resource) } before { @resource = create(:resource) }
let(:id) { resource.id } include in params block
let(:body) { { name: "x" } } include in params block
openapi_spec: metadata on describe openapi_spec "name.yaml" at class level
require "swagger_helper" require "openapi_helper"

Configuration

Miniswag.configure do |config|
  # Required — where to write generated spec files
  config.openapi_root = Rails.root.join("docs/api").to_s

  # Required — spec definitions (supports multiple files)
  config.openapi_specs = { "v1.yaml" => { openapi: "3.0.1", info: { ... } } }

  # Optional — output format (:json or :yaml, default :yaml)
  config.openapi_format = :yaml

  # Optional — strict schema validation (rejects additional properties)
  config.openapi_strict_schema_validation = false
end

Requirements

  • Ruby >= 3.1
  • Rails >= 7.0, < 9.0
  • Minitest ~> 5.0

License

MIT. See MIT-LICENSE.