Skip to main content
Shell command blocks let you run arbitrary shell commands after an HTTP request completes. This is useful for post-processing, triggering external scripts, or performing validation that goes beyond HTTP assertions.

Security

Shell command blocks execute arbitrary commands on your system. You must pass the --allow-shell flag to enable them. Without this flag, >>>shell blocks are skipped.
hitspec run tests/ --allow-shell

Basic Usage

Add a >>>shell block after your request and assertions:
### Process data
# @name processData

POST {{baseUrl}}/api/process
Content-Type: application/json

{
  "action": "generate-report"
}

>>>
expect status 200
<<<

>>>shell
echo "Processing complete"
./scripts/notify.sh
<<<
Shell commands execute after the HTTP assertions have been evaluated.

Variable Interpolation

Variables are resolved in shell commands before execution. You can use environment variables, captured values, and built-in functions:
### Create resource
# @name createResource

POST {{baseUrl}}/api/resources
Content-Type: application/json

{
  "name": "test-resource"
}

>>>
expect status 201
<<<

>>>capture
resourceId from body.id
<<<

>>>shell
echo "Created resource: {{createResource.resourceId}}"
curl -s {{baseUrl}}/api/resources/{{createResource.resourceId}} | jq .
<<<

Error Handling

By default, if a shell command fails (returns a non-zero exit code), the test fails. Prefix a command with - to ignore its exit code:
>>>shell
echo "This must succeed"
-rm temp-file-that-may-not-exist.txt
echo "Continues even if rm failed"
<<<
PrefixBehavior
(none)Fail the test if the command returns non-zero
-Ignore the exit code and continue

Execution Details

  • Commands run via sh -c
  • Working directory is the .http file location
  • Commands execute sequentially in the order they appear
  • Each line is a separate command
  • Standard output and standard error are captured

Examples

Verify a File Was Created

### Export data
# @name exportData

POST {{baseUrl}}/api/export

>>>
expect status 200
<<<

>>>shell
test -f ./output/export.csv
wc -l ./output/export.csv
<<<

Run a Cleanup Script

### Integration test
# @name integrationTest

POST {{baseUrl}}/api/test-data
Content-Type: application/json

{
  "seed": true
}

>>>
expect status 200
<<<

>>>shell
./scripts/verify-test-data.sh
-./scripts/cleanup.sh
<<<

Chain with External Tools

### Get API response
# @name getResponse

GET {{baseUrl}}/api/data

>>>
expect status 200
<<<

>>>shell
echo '{{getResponse.body}}' | jq '.items | length'
<<<
Shell blocks are meant for tasks that cannot be expressed as HTTP assertions. For most validation needs, use the built-in assertion operators instead.