Best practices for writing HTTPSpec test files with assertions
HTTPSpec allows you to write integration tests for HTTP APIs using familiar .http file syntax enhanced with assertions. This guide covers best practices for organizing and structuring your test files.
Use the ### comment syntax to name individual requests within a file:
### Get user by IDGET https://api.example.com/users/123//# status == 200### Get non-existent userGET https://api.example.com/users/999999//# status == 404
Test names appear in error messages, making failures easier to debug.
Use # or // for regular comments (not assertions):
# This is a comment// This is also a comment### Create user testPOST https://api.example.com/usersContent-Type: application/json// Request body{"name": "Alice"}//# status == 201 # This is an assertion, not a comment!
Assertions must start with //# (double slash, hash). Lines starting with // alone are treated as comments and ignored.
Here’s a complete example from the HTTPSpec test suite:
### Make a simple 200 request to HTTP BinGET http://httpbin.org/status/200Content-Type: application/json### Make a simple 404 request to HTTP BinGET http://httpbin.org/status/404Content-Type: application/json//# status == 403
In this example, the second request intentionally asserts status == 403 but receives a 404 response. This demonstrates how HTTPSpec stops execution on the first assertion failure.
Keep related sequential requests in the same file:
### Create userPOST https://api.example.com/usersContent-Type: application/json{"name": "Alice"}//# status == 201### Verify user was createdGET https://api.example.com/users/123//# status == 200//# body contains "Alice"
Don’t just check status codes - validate the actual response:
GET https://api.example.com/users/123//# status == 200//# header["content-type"] == "application/json"//# body contains "email"//# body contains "name"
### Test successful user creationPOST https://api.example.com/usersContent-Type: application/json{"name": "Alice"}//# status == 201//# body contains "Alice"
Since requests run sequentially within a file, order them logically:
### Setup: Create test userPOST https://api.example.com/usersContent-Type: application/json{"name": "Test User"}//# status == 201### Test: Fetch the created userGET https://api.example.com/users/123//# status == 200### Cleanup: Delete the test userDELETE https://api.example.com/users/123//# status == 204
If any assertion fails, subsequent requests in the file will not execute. Design your tests with this behavior in mind.