Skip to content

TestScript Operations

Operations are the actions performed during test execution. FHIR Frog supports all standard FHIR operations plus custom extensions.

Operation Types

Read

Read a resource by ID:

{
  "operation": {
    "type": {
      "system": "http://terminology.hl7.org/CodeSystem/testscript-operation-codes",
      "code": "read"
    },
    "resource": "Patient",
    "params": "/${patientId}",
    "responseId": "readResponse"
  }
}

Create

Create a new resource:

{
  "operation": {
    "type": {
      "code": "create"
    },
    "resource": "Patient",
    "sourceId": "patient-fixture",
    "responseId": "createResponse"
  }
}

Update

Update an existing resource:

{
  "operation": {
    "type": {
      "code": "update"
    },
    "resource": "Patient",
    "params": "/${patientId}",
    "sourceId": "updated-patient",
    "responseId": "updateResponse"
  }
}

Response status: 200 or 201

FHIR Frog reports the server's real HTTP status for update, not an assumed constant. A PUT to an existing resource typically returns 200, but 201 ("create via update") is equally valid FHIR if the target ID didn't already exist — assert whichever your server actually returns.

Delete

Delete a resource:

{
  "operation": {
    "type": {
      "code": "delete"
    },
    "resource": "Patient",
    "params": "/${patientId}"
  }
}

Search for resources:

{
  "operation": {
    "type": {
      "code": "search"
    },
    "resource": "Patient",
    "params": "?identifier=http://ns.electronichealth.net.au/id/medicare-number|32788511952",
    "responseId": "searchResponse"
  }
}

params is forwarded as the query string for search, the same way it's used as a path/query fragment for read, delete, and history. A leading ? is optional — FHIR Frog strips it if present. Omitting params entirely issues a bare, unparameterized search (GET [base]/Patient), which is unchanged, existing behaviour.

Batch/Transaction

Execute a bundle:

{
  "operation": {
    "type": {
      "code": "transaction"
    },
    "sourceId": "transaction-bundle",
    "responseId": "transactionResponse"
  }
}

Operation Parameters

type

The operation code (read, create, update, delete, search, etc.)

resource

The FHIR resource type (Patient, Observation, etc.)

params

URL parameters or path segments (e.g., /${id}, ?name=Smith)

sourceId

Reference to a fixture to use as the request body

responseId

ID to store the response for later assertions or variable extraction

requestHeader

Custom HTTP headers:

{
  "operation": {
    "type": {"code": "read"},
    "resource": "Patient",
    "params": "/${patientId}",
    "requestHeader": [
      {
        "field": "Accept",
        "value": "application/fhir+json"
      }
    ]
  }
}

Extended Operations

$validate

Validate a resource:

{
  "operation": {
    "type": {
      "code": "validate"
    },
    "resource": "Patient",
    "sourceId": "patient-to-validate",
    "responseId": "validateResponse"
  }
}

Custom Operations

Any FHIR operation can be invoked:

{
  "operation": {
    "type": {
      "code": "$everything"
    },
    "resource": "Patient",
    "params": "/${patientId}/$everything",
    "responseId": "everythingResponse"
  }
}

Best Practices

  1. Always use responseId for operations you'll assert against
  2. Use meaningful IDs like createPatientResponse not response1
  3. Store IDs in variables for reuse across tests
  4. Use fixtures for complex request bodies
  5. Clean up resources in teardown sections

Next Steps