Negative Testing¶
Test that your FHIR server correctly rejects invalid requests and returns appropriate error responses.
Why Negative Tests?¶
Conformance isn't just about accepting valid data — it's also about rejecting invalid data correctly. Negative tests verify:
- Missing required fields →
400 Bad Request - Unknown resources →
404 Not Found - Validation failures →
422 Unprocessable Entity - Unauthorized access →
401/403
Test 404 for Missing Resource¶
{
"test": [
{
"name": "Missing resource returns 404",
"action": [
{
"operation": {
"type": { "code": "read" },
"resource": "Patient",
"params": "/this-id-does-not-exist",
"responseId": "missingResponse"
}
},
{
"assert": {
"description": "Returns 404",
"responseCode": "404",
"warningOnly": false
}
}
]
}
]
}
Test Validation Failure (422)¶
Submit a resource that violates a profile constraint:
fixtures/invalid-patient.json
{
"resourceType": "Patient",
"identifier": [
{
"system": "http://ns.electronichealth.net.au/id/medicare-number",
"value": "not-a-valid-medicare-number"
}
]
}
{
"test": [
{
"name": "Invalid medicare number rejected",
"action": [
{
"operation": {
"type": { "code": "create" },
"resource": "Patient",
"sourceId": "invalid-patient",
"responseId": "createResponse"
}
},
{
"assert": {
"description": "Server rejects invalid identifier",
"responseCode": "422",
"warningOnly": false
}
}
]
}
]
}
Test Missing Required Field¶
If the profile requires name, assert the server rejects:
{
"assert": {
"description": "Patient without required name rejected",
"responseCode": "422",
"warningOnly": false
}
}
Assert OperationOutcome¶
When a server returns 4xx or 5xx, it should include an OperationOutcome.
Assert its presence:
{
"assert": {
"description": "Response includes OperationOutcome",
"resource": "OperationOutcome",
"warningOnly": false
}
}
Assert the error severity:
{
"assert": {
"description": "OperationOutcome has error issue",
"expression": "OperationOutcome.issue.where(severity='error').count() > 0",
"warningOnly": false
}
}
Test Conflicting Update¶
Test optimistic locking with If-Match:
{
"operation": {
"type": { "code": "update" },
"resource": "Patient",
"params": "/${patientId}",
"sourceId": "patient-update",
"responseId": "conflictResponse",
"requestHeader": [
{
"field": "If-Match",
"value": "W/\"outdated-version\""
}
]
}
}
{
"assert": {
"description": "Optimistic lock conflict returns 409",
"responseCode": "409",
"warningOnly": false
}
}
warningOnly vs Strict¶
| Setting | Behaviour |
|---|---|
"warningOnly": false |
Test fails if assertion fails — use for conformance requirements |
"warningOnly": true |
Warning logged, test continues — use for optional behaviour |
Use warningOnly: false for all negative tests to ensure strict conformance checking.
Next Steps¶
- Assertions — Full assertion reference
- Search Examples — Search operations
- Best Practices — Testing patterns