Skip to main content

A simple tool for testing JSON/HTTP APIs

Project description

skivvy

Try it out in the browser

Declarative integration testing for HTTP APIs.

Skivvy is a tiny, opinionated CLI tool that lets you write API tests as plain JSON files and run them from the terminal. No JS hooks. No GUI. No snapshots. You declare what you expect, and skivvy tells you if reality disagrees — with readable diffs when it does.

It works with REST, GraphQL, and anything else that speaks HTTP. It's built for CI/CD pipelines but just as useful on your local machine.

The core idea

Most API testing tools push you toward one of two bad patterns: writing imperative code in a language you didn't ask for, or snapshot-testing entire responses so every unrelated field change breaks your suite. Skivvy takes a different approach — assert only what you care about. Check the status code, a single field, a subset of a nested object, or the length of a list. Ignore the rest.

{ "url": "/api/items", "response": { "results": [{ "name": "Widget42" }] } }

That's it. That's a test.

▶ Try it in the playground

This works especially well with deeply nested responses like GraphQL, where you can match subsets without caring about the full envelope:

{
  "url": "/graphql",
  "method": "post",
  "body": { "query": "{ posts { id title author { name } tags } }" },
  "match_subsets": true,
  "match_every_entry": true,
  "response": {
    "errors": null,
    "data": {
      "posts": [{ "author": { "name": "$text" }, "tags": "$len_gt 0" }],
      "totalCount": "$gt 0"
    }
  }
}

Every post must have a named author and at least one tag. No GraphQL errors. You don't have to spell out the full response shape.

▶ Try it in the playground

Matchers can reach beyond string comparison — they can enforce constraints across entire collections:

{
  "url": "/users/all",
  "match_every_entry": true,
  "response": {
    "images": [{ "thumbnail": "$valid_url", "id": "$unique" }]
  }
}

Every user's thumbnail is a live, reachable URL. Every ID is unique across the whole list. Two invariants over an arbitrarily large dataset, in a few lines of JSON.

▶ Try it in the playground

What you get

  • All the HTTP plumbing you'd expect — every verb, headers, cookies, file uploads, form data, response chaining via variables and brace expansion
  • Subset matching — assert against deeply nested fields without specifying the full path
  • Built-in matchers$contains, $regexp, $len, $gt, $between, $valid_url, $date, $store/$fetch, approximate values with $~, and more — plus automatic negation ($!contains) for all of them (full list)
  • Custom matchers — drop a Python file with a match(expected, actual) function into a directory and it just works
  • Readable diffs — when a test fails, you see exactly what went wrong in a human-friendly format, with multiple diff styles to choose from
  • Flexible configuration — per-test overrides, environment configs, CLI flags, env vars, with a clear precedence order and sane defaults (full list)
  • Setup & teardown — use directory naming and include/exclude filters to control execution order
  • Deterministic execution — serial by default, predictable every time

Check out the playground for trying it from the comfort of your browser. It provides a basic unix shell, and allows you to edit and run test suites that examplify the list above. It also contains a running server, with responses you can edit as well.

Install

uvx skivvy --version                     # no install needed with uv
pipx run skivvy --version                # or pipx
pip install skivvy                       # or plain pip
docker run --rm hyrfilm/skivvy:examples  # or docker

Reference

  • Settings — all configuration options with defaults and descriptions
  • Matchers — all built-in matchers with usage examples
  • CLI help also includes skivvy --help-settings and skivvy --help-matchers if you want to explore available knobs before enabling more logging

MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

skivvy-0.811.tar.gz (31.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

skivvy-0.811-py3-none-any.whl (37.8 kB view details)

Uploaded Python 3

File details

Details for the file skivvy-0.811.tar.gz.

File metadata

  • Download URL: skivvy-0.811.tar.gz
  • Upload date:
  • Size: 31.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for skivvy-0.811.tar.gz
Algorithm Hash digest
SHA256 dc0a31a2183d1f9108d16dbed93a60c92a832d5e08f3d183efa79add3cdf7413
MD5 564cc8b358f35e18bee41b9777d3e0aa
BLAKE2b-256 ed8a43aebf355c9b231a1b97808871317e399de7504b4f9f81624f27de692f97

See more details on using hashes here.

Provenance

The following attestation bundles were made for skivvy-0.811.tar.gz:

Publisher: on-release.yml on hyrfilm/skivvy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file skivvy-0.811-py3-none-any.whl.

File metadata

  • Download URL: skivvy-0.811-py3-none-any.whl
  • Upload date:
  • Size: 37.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for skivvy-0.811-py3-none-any.whl
Algorithm Hash digest
SHA256 0da2b539655fb568fdab72812fab0cc19c8a321faf41350d1a325001ab189234
MD5 40ba19362b27e559dd0d4495a1c05b38
BLAKE2b-256 01360070a486ac2c64ff2bd6ed85a3835135328c1ca3e2816b61e95c3c6b73e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for skivvy-0.811-py3-none-any.whl:

Publisher: on-release.yml on hyrfilm/skivvy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page