OpenAPI and Swagger Specifications

8 min read

If contract testing is one approach to "the API contract," OpenAPI is the other. Where Pact captures the consumer's needs, OpenAPI captures the provider's declared API: every endpoint, every parameter, every response shape, written down in a machine-readable file that both humans and tools can use. As a QA engineer, an OpenAPI spec is one of the most useful artefacts you can have access to — it lets you generate tests, validate responses, mock servers, and detect breaking changes automatically. This lesson explains the format and the ecosystem around it.

OpenAPI vs Swagger — same thing, different names

Both names refer to the same standard.

  • Swagger was the original name, created in 2011 by Smartbear. It included a spec format, a UI, and code generators.
  • In 2015 the spec was renamed OpenAPI and donated to the Linux Foundation. The Swagger brand now refers to the tooling (Swagger Editor, Swagger UI, Swagger Codegen), while OpenAPI Specification (OAS) refers to the format itself.

In practice you'll hear both names used interchangeably. When someone says "the swagger doc" they mean the OpenAPI spec file.

What the spec looks like

An OpenAPI document is a YAML or JSON file describing your API. A minimal slice for GET /users and POST /users:

openapi: 3.0.0
info:
  title: User Service
  version: 1.2.0
paths:
  /users:
    get:
      summary: List all users
      parameters:
        - name: role
          in: query
          schema:
            type: string
            enum: [admin, editor, viewer]
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
      responses:
        "200":
          description: List of users
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/User"
    post:
      summary: Create a user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UserInput"
      responses:
        "201":
          description: Created
        "409":
          description: Email already exists
components:
  schemas:
    User:
      type: object
      required: [id, name, email]
      properties:
        id: { type: integer }
        name: { type: string }
        email: { type: string, format: email }
        role: { type: string, enum: [admin, editor, viewer] }

Read it top to bottom: the title and version describe the API as a whole; paths enumerates each URL; each path lists the verbs supported, with parameters, request body, and possible responses; components.schemas defines reusable types referenced via $ref.

That single file is simultaneously documentation, schema definition, and test contract.

The OpenAPI ecosystem

Once your API has a spec, an entire toolchain becomes available:

OpenAPI spec
  • – Interactive docs
  • – Try it out
  • – Hosted at /docs
  • – Client SDKs
  • – Server stubs
  • – Multiple languages
  • – Prism (Stoplight)
  • – Mock examples
  • – Faster local dev
  • Schemathesis –
  • Dredd –
  • Postman import –
  • ajv –
  • openapi-validator –
  • Spec-vs-runtime checks –

Each branch is something you, as a tester, can lean on without writing it from scratch.

Swagger UI — the docs experience

Most teams host their OpenAPI spec at a known URL — typical paths are /api-docs, /swagger-ui, /openapi.yaml, or /openapi.json. Visit it in a browser and you usually get Swagger UI: an interactive page that lets you expand each endpoint, see parameters, and try requests with real auth.

For a tester, Swagger UI is the fastest way to:

  • Understand what endpoints exist.
  • Sanity-check what an endpoint returns for known inputs.
  • Generate a curl command from the form (most Swagger UIs have a "copy as curl" button).
  • Spot-check that the docs match reality.

Treat it as your first stop on a new API.

Generating tests from the spec

Two tools are worth knowing:

  • Schemathesis — Python-based, generates property-based tests from the spec. Hits every endpoint with a wide variety of inputs and validates responses against the schema. Catches surprising bugs in input handling.
    schemathesis run https://api.example.com/openapi.json --checks all
  • Dredd — language-agnostic, runs a fixed set of tests derived from the spec's examples. Less aggressive than Schemathesis but easier to integrate.
    dredd openapi.yaml https://api.example.com

Both tools are CI-friendly. The simplest CI step is "run schemathesis against staging — fail if any endpoint fails its own schema." That alone catches a startling fraction of real bugs.

Validating responses against the spec at runtime

In your hand-written tests, you can also validate every response against the spec's schema. Libraries like openapi-core (Python), openapi-validator-middleware (Node), or swagger-request-validator (Java) read the spec and validate live responses.

Pseudocode:

from openapi_core import OpenAPI
 
spec = OpenAPI.from_file("openapi.yaml")
 
def assert_matches_spec(response, path, method):
    spec.validate_response(path, method, response)

Add it to your test fixture and every API call gets a free schema check.

Detecting breaking changes between spec versions

Once the spec is checked into version control, changes to the spec are first-class signals. Tools like openapi-diff compare two versions and flag breaking changes:

  • Removed endpoints.
  • Renamed fields.
  • Tightened type constraints.
  • New required fields.

Wire this into a PR check: "if the spec change is breaking, require explicit approval and a deprecation note." That alone catches a lot of accidental breakage.

OpenAPI as documentation source of truth

The most powerful pattern: treat the OpenAPI spec as the single source of truth. Generate everything from it:

  • The provider's controller code (or annotations that produce the spec).
  • The consumer's client SDKs.
  • The docs page.
  • The tests.
  • The mock server.

When all of those are derived from the same file, the spec can't drift from reality — code generation enforces alignment. Teams that adopt this pattern often eliminate an entire category of "the docs say X but the API does Y" bugs.

Where to find the spec

For a public API:

  • The docs site usually has a "Download OpenAPI" link.
  • A common URL is https://api.example.com/openapi.json or /swagger.json or /v3/api-docs.
  • Some teams check the spec into the repo as openapi.yaml.

For an internal API where you can't find the spec:

  • Ask the team. The spec might be auto-generated and hosted at an unfamiliar path.
  • Look for annotations in the source code (@OpenAPI, @swagger, FastAPI's auto-generation, Spring's springdoc).
  • If no spec exists, that's a finding — the team might not realise how much testing leverage they're leaving on the table.

⚠️ Common mistakes

  • Trusting the spec uncritically. Specs drift. Always validate that endpoints actually exist and behave as documented before relying on the spec for test design.
  • Skipping spec-driven test generation. If you have a spec, Schemathesis or Dredd will write hundreds of useful tests for free. Not running them once is a missed opportunity.
  • Using example values as the only test inputs. Spec examples are illustrative. Test boundary cases, invalid inputs, and security cases too.

🎯 Practice task

Use a real OpenAPI spec end-to-end. 30 minutes.

  1. Open the Petstore example — the canonical OpenAPI demo.
  2. Click around the Swagger UI. Pick one endpoint (POST /pet is good) and identify each section: parameters, request body schema, possible responses.
  3. Download the raw spec from https://petstore3.swagger.io/api/v3/openapi.json. Skim the JSON.
  4. Find an OpenAPI spec for an API you actually care about — your own product, GitHub, Stripe, or any public API. Confirm the URL.
  5. Install Schemathesis (pip install schemathesis) and run it against an endpoint: schemathesis run https://petstore3.swagger.io/api/v3/openapi.json -E "/pet". Observe what it tests.
  6. Stretch: find one endpoint where the spec disagrees with reality (a parameter that no longer exists, a response field renamed). Write up the discrepancy as a bug — that's the everyday value of spec-driven testing.

You can now use OpenAPI specs to multiply your testing leverage. The final lesson of this chapter explores what to do when the docs and the API don't agree.

// tip to track lessons you complete and pick up where you left off across devices.