Dredd vs Schemathesis: Comparing API Contract Testing Tools
Both Dredd and Schemathesis test whether your API implementation matches its spec. Both read OpenAPI (or API Blueprint) definitions and make real HTTP requests. Beyond that, they take fundamentally different approaches — and understanding the difference determines which one belongs in your pipeline.
The Core Difference
Dredd is deterministic. It reads the examples from your spec and sends those exact requests. Each operation gets one test run, using the example values you defined. Pass/fail depends on whether the actual response matches the expected schema and status code.
Schemathesis is generative. It uses your schema definitions to generate hundreds or thousands of random inputs per endpoint. Each run explores different parts of the input space. It finds failures you didn't anticipate by testing inputs you wouldn't write manually.
This difference in philosophy drives everything else.
Dredd: Deterministic Contract Testing
How Dredd Works
Dredd processes your spec top to bottom. For each operation:
- Uses the
examplevalue from the request body or parameter definition - Sends the request to your running API
- Validates the response status code and body schema
npm install -g dredd
dredd openapi.yaml http://localhost:3000Output:
pass: GET /users/123 duration: 45ms
pass: POST /users duration: 67ms
fail: DELETE /users/123 - expected 204, got 200Writing Good Dredd Tests
Dredd's output quality depends entirely on your spec's examples. Endpoints without examples are skipped. Endpoints with shallow examples get shallow tests.
paths:
/users:
post:
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/CreateUser"
example:
email: "test@example.com"
name: "Test User"
role: "viewer"For operations that depend on state (create a user, then retrieve it), Dredd uses hooks — Node.js or Python scripts that run before and after requests:
// hooks.js
const hooks = require("hooks");
let userId;
hooks.after("POST /users", (transaction, done) => {
userId = JSON.parse(transaction.real.body).id;
done();
});
hooks.before("GET /users/{userId}", (transaction, done) => {
transaction.fullPath = `/users/${userId}`;
done();
});dredd openapi.yaml http://localhost:3000 --hookfiles=./hooks.jsDredd's Strengths
- Predictable — same inputs every run, deterministic results
- Fast — one request per operation, minimal overhead
- Good for smoke testing — quickly verifies every endpoint returns the right shape
- CI-friendly — zero flakiness, reproducible builds
Dredd's Weaknesses
- Only tests one input per endpoint — misses edge cases completely
- Requires detailed spec examples — endpoints without examples aren't tested
- Manual state management — hooks add complexity for stateful scenarios
- Doesn't find unexpected failures — only checks what you've explicitly described
Schemathesis: Property-Based Contract Testing
How Schemathesis Works
Schemathesis uses the Hypothesis library under the hood. For each operation:
- Analyzes the parameter schemas to understand the input space
- Generates diverse inputs: edge cases, boundary values, random combinations
- Sends many requests and checks all responses for spec violations
- Shrinks failures to minimal reproducing examples
pip install schemathesis
st run http://localhost:8000/openapi.yaml --url http://localhost:8000One Schemathesis run might generate 50-200 requests per endpoint, exploring inputs like:
- Empty strings for string fields
- Maximum integer values
- Unicode characters in text fields
- Missing optional parameters
- Null values for nullable fields
Schemathesis's Strengths
- Finds bugs you didn't think of — systematically explores edge cases
- Minimal example reproduction — shrinks failures to smallest triggering input
- No example maintenance — generates inputs from schema definitions
- Catches crashes — specifically looks for 5xx responses to valid inputs
- Stateful testing via links — follows OpenAPI links to test multi-step scenarios
Schemathesis's Weaknesses
- Non-deterministic — different runs may find different bugs (or none)
- Slower — many requests per endpoint vs. one for Dredd
- Requires authentication setup — more configuration for protected APIs
- Can generate noisy data — random inputs may require more careful server-side handling of unexpected values
Side-by-Side Comparison
| Aspect | Dredd | Schemathesis |
|---|---|---|
| Test approach | Example-based | Property-based |
| Requests per endpoint | 1 | 50-500+ |
| Requires spec examples | Yes | No |
| Finds edge cases | No | Yes |
| Deterministic | Yes | No |
| CI speed | Fast | Slower |
| State management | Hooks (manual) | OpenAPI Links (semi-automatic) |
| Bug discovery | Only known scenarios | Unknown scenarios too |
| Setup complexity | Low | Medium |
When to Use Dredd
Dredd is the right choice when:
- You need fast, deterministic CI gates — Dredd is a smoke test that verifies every endpoint is up and returning the right shape
- Your spec has detailed examples — if you've invested in good example values, Dredd makes direct use of them
- You want simple setup — Dredd's configuration is minimal and its output is easy to read
- Testing for regressions — if the API worked yesterday and you want to confirm it still works today
When to Use Schemathesis
Schemathesis is the right choice when:
- You're testing a new API — property testing finds bugs during development, before users do
- Security is a concern — Schemathesis's random inputs are similar to fuzzing, catching injection vulnerabilities and unhandled edge cases
- You've had production incidents from unexpected inputs — one Schemathesis run might have caught the bug that caused the incident
- You want confidence beyond the happy path — if your spec defines valid inputs, Schemathesis tests them all
Using Both Together
The tools complement each other well. A practical pipeline:
# .github/workflows/api-tests.yml
name: API Tests
on: [push]
jobs:
dredd:
name: Contract Smoke Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install -g dredd
- run: dredd openapi.yaml ${{ env.API_URL }}
schemathesis:
name: Property-Based Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: schemathesis/action@v1
with:
schema: "${{ env.API_URL }}/openapi.yaml"
args: "--checks all"Dredd runs on every commit as a fast gate. Schemathesis runs in a separate job — slower, but catches bugs the smoke test misses. Failures in either job block the merge.
The Verdict
For most teams, the practical answer is:
- Start with Schemathesis if you're building a new API — it finds real bugs during development
- Add Dredd once the API is stable — it's a fast regression guard for CI
- Run Schemathesis nightly with higher example counts — deeper exploration when build times don't matter
Neither tool replaces the other. Dredd verifies your known-good examples still work. Schemathesis discovers what you didn't know to test. Together, they give you both speed and coverage.
For teams that also need behavioral end-to-end test coverage — verifying the user journeys that combine multiple API calls — HelpMeTest provides plain-English test automation that works alongside spec-driven tools.