Skip to main content

HTTP Status Validation

Welcome to the HTTP Status Validation documentation!

HTTP Status code assertions are the most fundamental type of API validation. They allow you to define what HTTP response codes are considered "successful" for a given request.

Use this guide to learn how to assert on exact status codes and ranges in the Rumour API testing ecosystem.

Exact Status Code Match (status)

To verify that an endpoint returns a specific, exact status code, use the status field inside the [assert] block.

Example: Exact Match

status_exact.toml

name = "status_validation_demo"

[request]
method = "GET"
url = "{{base_url}}/users/1"

[assert]
status = 200

Output (Success)

When the server responds with a 200 status, the test passes. Running this node with the verbose (-v) flag produces a detailed trace:

rumour run ./status_exact.toml -v
GET http://localhost:4000/api/v2/users/1
URL: http://localhost:4000/api/v2/users/1
✓ SUCCESS: /home/bugsfounder/workspace/testing/assertion_examples/status_exact.toml (3ms)
✓ ./status_exact.toml → PASS (1 Pass, 0 Fail, 0 Skip)
╭──────────────────────────────────────────────────────────────────────────╮
│ RUMOUR EXECUTION REPORT │
├──────────────────────────────────────────────────────────────────────────┤
│ Total Requests: 1
│ Successful: 1
│ Failed: 0
│ Skipped: 0
│ Success Rate: 100.0% │
│ Total Time: 6ms │
╰──────────────────────────────────────────────────────────────────────────╯

✓ Successful Requests:
- /home/bugsfounder/workspace/testing/assertion_examples/status_exact.toml [200] [6ms]

Let's break down what just happened:

When you run Rumour with the -v (verbose) flag, it prints out exactly what it's doing behind the scenes in real-time.

  1. The Live Action: First, it shows the HTTP method (GET) and the exact URL it's calling. When the server responds with a 200, it immediately prints a green ✓ SUCCESS along with how fast the request took to complete (3ms).
  2. The Big Picture: Once all requests in the file are done, Rumour generates a nice little dashboard (RUMOUR EXECUTION REPORT). This tells you at a glance that 1 request fired, 1 succeeded, and your success rate is a perfect 100.0%.
  3. The Roll Call: Finally, under ✓ Successful Requests, it lists the exact files that passed, showing you the status code they received ([200]) and their individual latencies.

Output (Failure)

If you assert status = 201, but the server returns a 200, the assertion fails and halts the pipeline with a non-zero exit code:

~/workspace/testing main* ❯ rumour run ./assertion_examples/status_fail.toml -v
GET http://localhost:4000/api/v2/users/1
URL: http://localhost:4000/api/v2/users/1
✗ FAILED: /home/bugsfounder/workspace/testing/assertion_examples/status_fail.toml (3ms) - HTTP Status: Expected status 201, got 200
↻ RETRYING: /home/bugsfounder/workspace/testing/assertion_examples/status_fail.toml (Attempt 1/2) [Wait 500ms]
GET http://localhost:4000/api/v2/users/1
URL: http://localhost:4000/api/v2/users/1
✗ FAILED: /home/bugsfounder/workspace/testing/assertion_examples/status_fail.toml (1ms) - HTTP Status: Expected status 201, got 200
↻ RETRYING: /home/bugsfounder/workspace/testing/assertion_examples/status_fail.toml (Attempt 2/2) [Wait 1000ms]
GET http://localhost:4000/api/v2/users/1
URL: http://localhost:4000/api/v2/users/1
✗ FAILED: /home/bugsfounder/workspace/testing/assertion_examples/status_fail.toml (1ms) - HTTP Status: Expected status 201, got 200
✗ ./assertion_examples/status_fail.toml → FAIL (0 Pass, 1 Fail, 0 Skip)
╭──────────────────────────────────────────────────────────────────────────╮
│ RUMOUR EXECUTION REPORT │
├──────────────────────────────────────────────────────────────────────────┤
│ Total Requests: 1
│ Successful: 0
│ Failed: 1
│ Skipped: 0
│ Success Rate: 0.0% │
│ Total Time: 1514ms │
╰──────────────────────────────────────────────────────────────────────────╯

✗ Failed Requests:
- /home/bugsfounder/workspace/testing/assertion_examples/status_fail.toml: [200]
Reason: HTTP Status: Expected status 201, got 200

Actionable Recommendations:
→ Run with -H (Self-Healing) to attempt automatic recovery of failing nodes.

Let's break down what just happened:

This output is much longer because Rumour is trying its best to make the request pass before giving up!

  1. The First Failure: Rumour sends the request, but the server replies with a 200 instead of the 201 we explicitly asked for. Rumour immediately flags this as an ✗ FAILED assertion.
  2. The Built-in Retries: Because you might be dealing with a flaky network or a server that's still booting up, Rumour automatically tries again (↻ RETRYING). Notice how it waits 500ms for the first retry, and then waits 1000ms for the second? That's Rumour's smart exponential backoff kicking in!
  3. Giving Up: After exhausting all its retry attempts, Rumour officially marks the file as a FAIL.
  4. The Post-Mortem: In the RUMOUR EXECUTION REPORT, you see your success rate is 0.0%. More importantly, the ✗ Failed Requests block at the bottom tells you exactly why it failed in plain English: Expected status 201, got 200. No need to go digging through log files!
  5. Helpful Hints: To be extra helpful, Rumour provides an Actionable Recommendations section at the very end, suggesting you try running the command again with the -H flag to enable its advanced Self-Healing engine.

Status Range Match (status_range)

Sometimes, an endpoint might return different success codes depending on the state (e.g., 200 OK or 201 Created or 204 No Content). You can validate against multiple acceptable codes using status_range.

Defining Ranges

The status_range field supports several formats:

  • Hyphenated Range: "200-299" (Any status from 200 to 299 inclusive)
  • Comma-Separated List: "200,201,204" (Only exactly 200, 201, or 204)
  • Single String Value: "200" (Acts exactly like status = 200)

Example: Range Match

status_range.toml

name = "status_range_demo"

[request]
method = "GET"
url = "{{base_url}}/users/1"

[assert]
status_range = "200-299"

Output (Success)

When the endpoint returns any status within the configured range (e.g., 200), it is treated as a successful execution:

rumour run ./status_range.toml -v
GET http://localhost:4000/api/v2/users/1
URL: http://localhost:4000/api/v2/users/1
✓ SUCCESS: /home/bugsfounder/workspace/testing/assertion_examples/status_range.toml (1ms)
✓ ./status_range.toml → PASS (1 Pass, 0 Fail, 0 Skip)
╭──────────────────────────────────────────────────────────────────────────╮
│ RUMOUR EXECUTION REPORT │
├──────────────────────────────────────────────────────────────────────────┤
│ Total Requests: 1
│ Successful: 1
│ Failed: 0
│ Skipped: 0
│ Success Rate: 100.0% │
│ Total Time: 3ms │
╰──────────────────────────────────────────────────────────────────────────╯

✓ Successful Requests:
- /home/bugsfounder/workspace/testing/assertion_examples/status_range.toml [200] [3ms]

Let's break down what just happened:

Notice anything familiar? The output looks exactly the same as a single-status match!

Even though you told Rumour to accept any code between 200 and 299, it cleanly hides all that logic from your terminal. It simply sees the 200 response, verifies that it falls inside your acceptable range, and marks the test as a ✓ SUCCESS. This keeps your final execution reports clean, standardized, and easy to read, no matter how complex your range logic gets.