Skip to content

TestScript Fixtures

Fixtures are test data resources used as request bodies in operations. They provide consistent, reusable test data.

How Fixtures Work

Fixtures are managed through the client-side ResourceSpace — an in-memory map of named FHIR resources that exists for the duration of a test execution. Loading happens in two phases:

  1. Phase 1 (Load) — All fixture resources are read from files and registered in the ResourceSpace. No server interaction occurs.
  2. Phase 2 (Autocreate) — Fixtures marked autocreate=true are submitted to the server as a single FHIR transaction bundle. Before submission, cross-fixture references are rewritten to urn:uuid: form and circular references are detected. After the response, server-assigned IDs are written back into the ResourceSpace.

This means fixtures are always available locally (for assertions, variable extraction, etc.) regardless of whether they were created on the server.

Cross-Fixture Reference Rewriting

When autocreate fixtures reference each other, those references are automatically rewritten before the transaction is submitted:

Fixture A (Observation):  subject.reference = "Patient/patient-fixture"
Fixture B (Patient):      id = "patient-fixture"

→ Before submission, A's reference becomes "urn:uuid:patient-fixture"
→ The transaction bundle entry for B has fullUrl = "urn:uuid:patient-fixture"
→ The server resolves the reference within the bundle

Circular references (A → B → A) are detected via depth-first search and rejected with an IllegalStateException before the bundle is submitted.

Basic Fixture

Define Fixture

{
  "fixture": [
    {
      "id": "patient-example",
      "resource": {
        "resourceType": "Patient",
        "name": [
          {
            "family": "Smith",
            "given": ["John"]
          }
        ],
        "gender": "male",
        "birthDate": "1974-12-25"
      }
    }
  ]
}

Use in Operation

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

External Fixtures

Load from files:

{
  "fixture": [
    {
      "id": "au-core-patient",
      "resource": {
        "reference": "Patient/au-core-patient-example.json"
      }
    }
  ]
}

AU Core Examples

Patient with Medicare Number

{
  "fixture": [
    {
      "id": "au-patient-medicare",
      "resource": {
        "resourceType": "Patient",
        "identifier": [
          {
            "type": {
              "coding": [
                {
                  "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
                  "code": "MC"
                }
              ]
            },
            "system": "http://ns.electronichealth.net.au/id/medicare-number",
            "value": "32788511952"
          }
        ],
        "name": [
          {
            "family": "Smith",
            "given": ["John"]
          }
        ],
        "gender": "male"
      }
    }
  ]
}

Practitioner with HPI-I

{
  "fixture": [
    {
      "id": "au-practitioner-hpii",
      "resource": {
        "resourceType": "Practitioner",
        "identifier": [
          {
            "type": {
              "coding": [
                {
                  "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
                  "code": "NPI"
                }
              ]
            },
            "system": "http://ns.electronichealth.net.au/id/hi/hpii/1.0",
            "value": "8003610000000000"
          }
        ],
        "name": [
          {
            "family": "Doctor",
            "given": ["Jane"],
            "prefix": ["Dr"]
          }
        ]
      }
    }
  ]
}

Organization with HPI-O

{
  "fixture": [
    {
      "id": "au-organization-hpio",
      "resource": {
        "resourceType": "Organization",
        "identifier": [
          {
            "type": {
              "coding": [
                {
                  "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
                  "code": "NOI"
                }
              ]
            },
            "system": "http://ns.electronichealth.net.au/id/hi/hpio/1.0",
            "value": "8003620000000000"
          }
        ],
        "name": "Example Hospital"
      }
    }
  ]
}

Transaction Bundle Fixtures

Bundle with Multiple Resources

{
  "fixture": [
    {
      "id": "observation-bundle",
      "resource": {
        "resourceType": "Bundle",
        "type": "transaction",
        "entry": [
          {
            "fullUrl": "urn:uuid:patient-1",
            "request": {
              "method": "POST",
              "url": "Patient"
            },
            "resource": {
              "resourceType": "Patient",
              "name": [{"family": "Smith", "given": ["John"]}]
            }
          },
          {
            "fullUrl": "urn:uuid:observation-1",
            "request": {
              "method": "POST",
              "url": "Observation"
            },
            "resource": {
              "resourceType": "Observation",
              "status": "final",
              "code": {
                "coding": [
                  {
                    "system": "http://loinc.org",
                    "code": "85354-9"
                  }
                ]
              },
              "subject": {
                "reference": "urn:uuid:patient-1"
              }
            }
          }
        ]
      }
    }
  ]
}

Fixture Patterns

Minimal Valid Resource

{
  "id": "minimal-patient",
  "resource": {
    "resourceType": "Patient"
  }
}

Invalid Resource (for negative tests)

{
  "id": "invalid-patient",
  "resource": {
    "resourceType": "Patient",
    "gender": "invalid-code",
    "birthDate": "not-a-date"
  }
}

Resource with References

{
  "id": "observation-with-ref",
  "resource": {
    "resourceType": "Observation",
    "status": "final",
    "code": {
      "coding": [{"system": "http://loinc.org", "code": "85354-9"}]
    },
    "subject": {
      "reference": "Patient/${patientId}"
    }
  }
}

Dynamic Fixtures

Use variables in fixtures:

{
  "fixture": [
    {
      "id": "updated-patient",
      "resource": {
        "resourceType": "Patient",
        "id": "${patientId}",
        "name": [
          {
            "family": "UpdatedName",
            "given": ["John"]
          }
        ]
      }
    }
  ]
}

Fixture Organization

By Resource Type

fixtures/
  patient/
    basic.json
    with-medicare.json
    with-ihi.json
  practitioner/
    with-hpii.json
    with-ahpra.json
  organization/
    with-hpio.json
    with-abn.json

By Test Scenario

fixtures/
  crud/
    patient-create.json
    patient-update.json
  search/
    patient-searchable.json
  validation/
    patient-invalid.json

Shared Fixtures

Reuse across multiple tests:

{
  "fixture": [
    {
      "id": "standard-patient",
      "resource": {
        "reference": "fixtures/patient/standard.json"
      }
    }
  ]
}

Best Practices

  1. Use external files - Keep TestScripts clean and fixtures reusable
  2. Meaningful IDs - au-patient-medicare not fixture1
  3. Minimal data - Only include required fields unless testing specific scenarios
  4. Valid by default - Use separate fixtures for invalid data
  5. Document identifiers - Comment Australian identifier systems
  6. Version control - Track fixture changes alongside tests

Fixture Validation

Validate fixtures before use:

{
  "action": [
    {
      "operation": {
        "type": {"code": "validate"},
        "sourceId": "patient-fixture",
        "responseId": "validateResponse"
      }
    },
    {
      "assert": {
        "expression": "OperationOutcome.issue.where(severity='error').count() = 0",
        "description": "Fixture must be valid"
      }
    }
  ]
}

Fixture Library

Build a reusable library:

// fixtures/library.json
{
  "resourceType": "Bundle",
  "type": "collection",
  "entry": [
    {
      "fullUrl": "Patient/example-medicare",
      "resource": { /* Patient with Medicare */ }
    },
    {
      "fullUrl": "Practitioner/example-hpii",
      "resource": { /* Practitioner with HPI-I */ }
    }
  ]
}

Next Steps