User Guide

Learn how to effectively use HTTP File Runner for testing APIs, automation, and more.

Getting Started

HTTP File Runner is a command-line tool that executes HTTP requests defined in .http files. It's perfect for API testing, automation, and development workflows.

Basic Usage

# Run a single .http file httprunner requests.http # Run multiple files httprunner file1.http file2.http # Discover and run all .http files recursively httprunner --discover

Output Modes

  • Default: Shows request results with colored status indicators
  • Verbose (--verbose): Shows detailed request/response information
  • Logging (--log): Saves output to a file for analysis
  • Report (--report): Generates markdown summary report with test results and statistics

HTTP File Format

HTTP files use a simple, readable format that's compatible with many tools and editors.

Basic Structure

# Comments start with # # Simple GET request GET https://api.example.com/users # Request with headers GET https://api.example.com/data Authorization: Bearer your-token Accept: application/json # POST request with body POST https://api.example.com/users Content-Type: application/json { "name": "John Doe", "email": "john@example.com" }

Supported HTTP Methods

  • GET
  • POST
  • PUT
  • DELETE
  • PATCH

Headers and Body

Headers are specified as key-value pairs separated by colons. The request body comes after a blank line following the headers.

Variables

Variables make your HTTP files flexible and reusable across different environments and scenarios.

Defining Variables

# Define variables with @ syntax @hostname=localhost @port=8080 @version=v1 @baseUrl=https://{{hostname}}:{{port}}/api/{{version}}

Using Variables

# Use variables with double curly braces GET {{baseUrl}}/users # Variables in headers GET {{baseUrl}}/protected Authorization: Bearer {{token}} # Variables in request body POST {{baseUrl}}/users Content-Type: application/json { "host": "{{hostname}}", "environment": "{{env}}" }

Variable Composition

Variables can reference other variables that were defined earlier:

@hostname=api.example.com @protocol=https @baseUrl={{protocol}}://{{hostname}} GET {{baseUrl}}/status

Request Variables

Request Variables enable powerful request chaining by allowing you to pass data from one HTTP request to another within the same .http file.

Syntax

Request variables follow this pattern:

{{<request_name>.(request|response).(body|headers).(*|JSONPath|XPath|<header_name>)}}

Authentication Flow Example

# @name authenticate POST https://httpbin.org/post Content-Type: application/json { "username": "admin@example.com", "password": "secure123", "access_token": "jwt_token_here", "refresh_token": "refresh_jwt_here", "user_id": "admin_001", "role": "administrator" } ### # @name get_admin_data GET https://httpbin.org/get Authorization: Bearer {{authenticate.response.body.$.json.access_token}} X-User-Role: {{authenticate.response.body.$.json.role}} X-User-ID: {{authenticate.response.body.$.json.user_id}} ### # @name create_audit_log POST https://httpbin.org/post Content-Type: application/json { "action": "admin_data_access", "user_id": "{{authenticate.response.body.$.json.user_id}}", "original_request": { "username": "{{authenticate.request.body.$.username}}", "timestamp": "2025-07-01T21:16:46Z" }, "response_content_type": "{{get_admin_data.response.headers.Content-Type}}" }

Extraction Patterns

JSON Bodies

  • $.property_name - Extract top-level properties
  • $.nested.property - Extract nested properties
  • $.json.property - Extract from "json" field (like httpbin.org responses)
  • * - Extract entire body

Headers

  • header_name - Extract specific header value (case-insensitive)

Request Data

  • Same patterns as response, but extracts from the original request data

💡 Use Cases

  • Authentication Workflows: Extract tokens from login responses
  • Data Chaining: Pass IDs or data between sequential requests
  • Dynamic Headers: Use response headers in subsequent requests
  • Request Auditing: Reference original request data in follow-up calls
  • API Testing: Create comprehensive test flows with dependent requests

Conditional Execution

Execute HTTP requests conditionally based on previous request results using @dependsOn, @if, and @if-not directives. This enables complex integration testing scenarios and workflow automation.

@dependsOn Directive

Execute a request only if a dependent request returns HTTP 200 status.

# @name check-user GET https://api.example.com/user/123 ### # Only execute if check-user succeeds (returns 200) # @name update-user # @dependsOn check-user PUT https://api.example.com/user/123 Content-Type: application/json { "name": "Updated Name" }

@if Directive - Status Code Check

Execute a request only if a previous request returns a specific HTTP status code.

# @name check-user GET https://api.example.com/user/123 ### # Create user only if they don't exist (404) # @name create-user # @if check-user.response.status 404 POST https://api.example.com/user Content-Type: application/json { "username": "newuser", "email": "user@example.com" }

@if Directive - JSONPath Body Check

Execute a request only if a JSONPath expression in the response body matches an expected value.

# @name create-user POST https://api.example.com/user Content-Type: application/json { "username": "testuser", "role": "admin" } ### # Update only if user was created with admin role # @name activate-admin # @if create-user.response.status 200 # @if create-user.response.body.$.username testuser # @if create-user.response.body.$.role admin PUT https://api.example.com/user/activate

@if-not Directive - Negated Conditions

Execute a request only if a condition does NOT match. Works the opposite way of @if.

# @name check-user GET https://api.example.com/user/123 ### # Update only if user exists (NOT 404) # @name update-user # @if-not check-user.response.status 404 PUT https://api.example.com/user/123 Content-Type: application/json { "name": "Updated Name" } ### # Create only if user does not exist (NOT 200) # @name create-user # @if-not check-user.response.status 200 POST https://api.example.com/user Content-Type: application/json { "id": 123, "name": "New User" } ### # Execute only if no error in response # @name process-result # @if create-user.response.status 200 # @if-not create-user.response.body.$.error true PUT https://api.example.com/user/activate

Multiple Conditions

Multiple @if and @if-not directives can be specified for a single request. All conditions must be met for the request to execute (AND logic).

# @name login POST https://api.example.com/login Content-Type: application/json { "username": "admin", "password": "secret" } ### # Only execute if login succeeded AND returned admin role # @name admin-dashboard # @if login.response.status 200 # @if login.response.body.$.role admin GET https://api.example.com/admin/dashboard Authorization: Bearer {{login.response.body.$.token}}

💡 Use Cases

  • Progressive User Setup: Check if user exists → Create only if 404 → Verify → Update
  • Error Handling: Try primary API → Use fallback if primary fails
  • Conditional Updates: Update resources only when specific conditions are met
  • Role-Based Testing: Execute admin-only requests based on user role
  • Data Validation: Proceed only if response data matches expectations
  • Negative Conditions with @if-not: Execute actions when something does NOT match (e.g., no errors, not 404, user does not exist)

📝 Notes

  • Conditional directives support both # and // comment styles
  • Requests can have both @dependsOn and multiple @if or @if-not directives
  • @if-not works as the opposite of @if - condition must NOT match to execute
  • Conditions can only reference requests that appear earlier in the .http file
  • All request names used in conditions must be defined with # @name
  • Skipped requests show: ⏭️ request-name - Skipped: conditions not met

Environment Files

Environment files allow you to define different variable values for different environments (dev, staging, production).

Creating Environment Files

Create a file named http-client.env.json in the same directory as your .http files:

{ "dev": { "HostAddress": "https://localhost:44320", "ApiKey": "dev-api-key-123", "Database": "development" }, "staging": { "HostAddress": "https://staging.example.com", "ApiKey": "staging-api-key-456", "Database": "staging" }, "prod": { "HostAddress": "https://api.example.com", "ApiKey": "prod-api-key-789", "Database": "production" } }

Using Environment Variables

# Use environment variables in .http files GET {{HostAddress}}/api/users Authorization: Bearer {{ApiKey}} X-Database: {{Database}}

Specifying Environment

# Use specific environment httprunner requests.http --env dev httprunner requests.http --env prod

Variable Override Priority

  1. Environment variables (loaded first)
  2. Variables in .http file (override environment variables)

Response Assertions

Assertions allow you to validate HTTP responses automatically, making your tests more reliable.

Assertion Types

# Status code assertion GET https://api.example.com/users EXPECTED_RESPONSE_STATUS 200 # Response body content assertion GET https://api.example.com/users/1 EXPECTED_RESPONSE_STATUS 200 EXPECTED_RESPONSE_BODY "John Doe" # Response header assertion GET https://api.example.com/data EXPECTED_RESPONSE_STATUS 200 EXPECTED_RESPONSE_HEADERS "Content-Type: application/json"

Multiple Assertions

GET https://api.example.com/users EXPECTED_RESPONSE_STATUS 200 EXPECTED_RESPONSE_BODY "users" EXPECTED_RESPONSE_HEADERS "Content-Type: application/json" EXPECTED_RESPONSE_HEADERS "Cache-Control: no-cache"

Assertion Behavior

  • Status Code: Exact match required
  • Response Body: Substring match (response must contain the expected text)
  • Response Headers: Header must exist and contain the expected value
  • Request Success: All assertions must pass for the request to be considered successful

Command Line Options

Basic Options

httprunner file.http
Run a single .http file
httprunner file1.http file2.http
Run multiple .http files
--discover
Recursively find and run all .http files

Output Options

--verbose
Show detailed request and response information
--pretty-json
Pretty-print JSON payloads in verbose output (requires --verbose)
--log
Save output to 'log' file
--log filename.txt
Save output to specified file
--report
Generate timestamped markdown summary report with test results and statistics

Environment Options

--env dev
Use 'dev' environment from http-client.env.json
--version, -v
Show version information

Examples

API Testing

# Test user registration and login flow @baseUrl=https://api.example.com # Register new user POST {{baseUrl}}/auth/register Content-Type: application/json { "username": "testuser", "email": "test@example.com", "password": "securepass123" } EXPECTED_RESPONSE_STATUS 201 EXPECTED_RESPONSE_BODY "user created" # Login POST {{baseUrl}}/auth/login Content-Type: application/json { "email": "test@example.com", "password": "securepass123" } EXPECTED_RESPONSE_STATUS 200 EXPECTED_RESPONSE_BODY "token"

Health Checks

# Monitor service health GET https://api.example.com/health EXPECTED_RESPONSE_STATUS 200 EXPECTED_RESPONSE_BODY "healthy" # Check database connectivity GET https://api.example.com/health/db EXPECTED_RESPONSE_STATUS 200 EXPECTED_RESPONSE_HEADERS "X-DB-Status: connected"

CRUD Operations

@baseUrl=https://jsonplaceholder.typicode.com # Create POST {{baseUrl}}/posts Content-Type: application/json { "title": "Test Post", "body": "This is a test post", "userId": 1 } EXPECTED_RESPONSE_STATUS 201 # Read GET {{baseUrl}}/posts/1 EXPECTED_RESPONSE_STATUS 200 # Update PUT {{baseUrl}}/posts/1 Content-Type: application/json { "id": 1, "title": "Updated Post", "body": "This post has been updated", "userId": 1 } EXPECTED_RESPONSE_STATUS 200 # Delete DELETE {{baseUrl}}/posts/1 EXPECTED_RESPONSE_STATUS 200

Best Practices

File Organization

  • Group related requests in the same .http file
  • Use descriptive file names (e.g., user-auth.http, health-checks.http)
  • Keep environment-specific files separate
  • Use comments to document complex requests

Variable Management

  • Define variables at the top of your .http files
  • Use descriptive variable names
  • Keep sensitive data in environment files, not in .http files
  • Use variable composition for complex URLs

Testing Strategy

  • Always include assertions for critical responses
  • Test both success and error scenarios
  • Use the --verbose flag when debugging
  • Generate reports with --report for test documentation and CI/CD integration
  • Save logs for CI/CD integration with --log

CI/CD Integration

# Example GitHub Actions step - name: Run API Tests run: | httprunner --discover --env staging --log test-results.log --report # Process test results and markdown report...

Performance Considerations

  • Use --discover for comprehensive testing
  • Consider request timing when testing rate limits
  • Monitor response times with --verbose output