0.0
No release in over 3 years
Open up your API to the OpenAPI ecosystem by exposing OpenAPI files, that describe your service, as JSON or YAML endpoints.
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
 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.