Chapter 17Lesson 05260–340 min

Checkpoint Lab — HTTP/API Automation, JSON Validation, and Service-Level Testing

Complete a local service-level checkpoint that creates, reads, validates, corrupts, diagnoses, and removes synthetic API records while preserving safe request/response and Robot evidence.

CheckpointCRUD-like APIFailure injectionEvidence packetRollback

Checkpoint objectives

  • Predict source/runtime/server/result changes before each operation.
  • Produce a deterministic health + CRUD-like contract suite against the loopback fixture.
  • Separate transport, JSON parsing, and business assertions in the evidence packet.
  • Inject malformed-response and wrong-expectation failures without changing the target or disabling trust checks.
  • Prove that cleanup removes only records owned by the current test.

Current compatibility baseline — verified 2026-08-31. Robot Framework 7.4.2 is the stable course baseline. The mandatory HTTP layer uses robotframework-requests 0.9.7, the latest stable RequestsLibrary release; the 1.0a series remains prerelease. The underlying Python Requests project is independently versioned; at generation time its stable release is 2.34.2. The lab uses Python 3.10+ for a single consistent environment even though Robot Framework itself supports Python 3.8+. All required targets are 127.0.0.1 loopback and all records/credentials are synthetic. No public API, paid service, browser, database, SSH target, Pabot, CI provider, or container runtime is required.

1. Scenario and safety boundary

You are creating a release-smoke evidence packet for a synthetic item service. The only approved target is http://127.0.0.1:8766. You will read health, create/read/delete one record, prove the record disappears, then exercise a deliberately malformed JSON response. No public endpoint, credential, database, browser, or external service is involved.

2. Exact preflight

python --version
python -m robot --version
python -m pip show robotframework-requests requests
# Confirm loopback health before test mutation:
python -c "import urllib.request; print(urllib.request.urlopen('http://127.0.0.1:8766/health', timeout=2).status)"

Record exact versions and the health status. Expected baseline: Robot 7.4.2; RequestsLibrary 0.9.7; Requests version recorded from your environment; loopback service returns 200.

3. Required project files

rf-api-lab/
├── fixture_api.py
├── resources/
│   └── api.resource
├── tests/
│   └── api_contract.robot
└── results/

Reuse the exact fixture_api.py and api.resource from Lesson 2. This checkpoint changes the test contract, not the service implementation.

4. Make predictions before execution

Prediction Verify independently after run
Health GET changes no server record fixture log + later first created ID remains 1
Create adds exactly one owned record and returns 201 + ID POST response JSON + subsequent GET
Delete removes that exact ID and returns 204 follow-up GET returns 404
Malformed endpoint returns HTTP 200 but JSON decoding fails response status/header + Robot failure/status evidence
Teardown does nothing after explicit successful delete OWNED_ITEM_ID reset to empty before teardown

5. Checkpoint suite

*** Settings ***
Resource    ../resources/api.resource
Suite Setup       Reset Local Fixture
Test Setup        Initialize Ownership
Test Teardown     Cleanup Owned Item

*** Test Cases ***
Health Contract Is Read Only
    ${headers}=    Build Safe Headers    rf-health-checkpoint
    ${response}=    GET    ${API_BASE}/health    headers=${headers}    timeout=${HTTP_TIMEOUT}    expected_status=200
    Response Correlation Should Be    ${response}    rf-health-checkpoint
    Dictionary Should Contain Item    ${response.json()}    status    ok

Create Read And Delete Owned Record
    ${item_id}    ${created}=    Create Demo Item    checkpoint-alpha    boundary    rf-create-checkpoint
    VAR    ${OWNED_ITEM_ID}    ${item_id}    scope=TEST
    Status Should Be    201    ${created}
    ${fetched}=    Get Demo Item    ${item_id}    rf-get-checkpoint
    Item Business Fields Should Be    ${fetched}    checkpoint-alpha    boundary
    ${deleted}=    Delete Demo Item    ${item_id}    rf-delete-checkpoint
    Status Should Be    204    ${deleted}
    VAR    ${OWNED_ITEM_ID}    ${EMPTY}    scope=TEST
    ${missing}=    Get Demo Item    ${item_id}    rf-confirm-delete    expected=any
    Status Should Be    404    ${missing}

Malformed JSON Is A Contract Failure
    ${headers}=    Build Safe Headers    rf-malformed-checkpoint
    ${response}=    GET    ${API_BASE}/malformed    headers=${headers}    timeout=${HTTP_TIMEOUT}    expected_status=200
    Response Correlation Should Be    ${response}    rf-malformed-checkpoint
    ${status}    ${message}=    Run Keyword And Ignore Error    Parse Response JSON    ${response}
    Should Be Equal    ${status}    FAIL
    Should Contain    ${message}    Expecting

*** Keywords ***
Initialize Ownership
    VAR    ${OWNED_ITEM_ID}    ${EMPTY}    scope=TEST

Cleanup Owned Item
    IF    $OWNED_ITEM_ID
        Delete Demo Item    ${OWNED_ITEM_ID}    rf-cleanup-${OWNED_ITEM_ID}    expected=any
    END

The malformed-JSON test deliberately converts the parsing failure into an inspected status/message because the purpose of this checkpoint case is to prove the failure contract. It must still assert that parsing actually failed. This is different from swallowing an unknown service error and continuing.

6. Run the controlled checkpoint

# PowerShell
.\.venv\Scripts\python -m robot --outputdir results\checkpoint tests\api_contract.robot

# Bash
./.venv/bin/python -m robot --outputdir results/checkpoint tests/api_contract.robot

Expected high-level result: the suite passes because the malformed-JSON case explicitly verifies that decoding fails. This is an intentional negative contract, not a false green. Inspect the log hierarchy and fixture log to confirm request sequence and correlation identifiers.

7. Failure injection A: wrong business expectation

Change only the expected name in the GET assertion from checkpoint-alpha to checkpoint-beta. Predict: transport remains 200, JSON parsing succeeds, the business assertion fails, teardown still removes the owned item, and the original failing run remains in its own output directory.

# Run into a separate directory; do not overwrite the passing evidence.
python -m robot --outputdir results/failure-business --test "Create Read And Delete Owned Record" tests/api_contract.robot

Repair the expected value, then rerun the single test into results/repaired-business. Compare the response status and the failing assertion message. This proves why transport and business evidence must be separate.

8. Failure injection B: malformed representation

Temporarily remove the negative-test wrapper around ${response.json()} so the decoding exception becomes a normal test failure. Preserve the HTTP 200 response, Content-Type, correlation header, safe fixture log line, and Robot exception. Then restore the explicit negative contract.

9. Redaction and retention policy exercise

Artifact Retention decision Redaction rule
Original output.xml retain through review/release evidence window never include real authorization values in source/logged args
log.html/report.html retain with access control avoid full sensitive bodies; synthetic lab data only
fixture stdout retain short checkpoint excerpt method/path/correlation only; no bodies/tokens
request/response samples retain selected fields only remove cookies/auth/PII; IDs synthetic
failure and repaired runs retain both until diagnosis is signed off do not overwrite first failure

10. Required evidence packet

  • Python, Robot Framework, RequestsLibrary, and Requests versions.
  • Exact loopback base URL and test command.
  • Health status/body and correlation ID.
  • Create response: method/path, 201, correlation header, synthetic ID, selected JSON fields.
  • Read response: 200 plus nested business assertions.
  • Delete response: 204 plus follow-up 404 proving state removal.
  • Malformed-response evidence: 200 transport + JSON decode failure.
  • Original wrong-expectation failure and repaired run in separate directories.
  • Fixture log excerpt containing only method/path/correlation.
  • Cleanup proof and a short retention/redaction policy.

11. Verification checklist

  • The only target is 127.0.0.1:8766.
  • Every HTTP call has a bounded timeout.
  • Success paths assert both transport and business outcomes.
  • Negative paths assert exact intended status/error behavior.
  • No TLS verification is disabled in any HTTPS example.
  • No real credentials, cookies, tokens, PII, public APIs, or production data appear.
  • No blanket retry, giant sleep, broad EXCEPT, or result deletion hides a failure.
  • Each created record is owned and removed by the test that created it.
  • First failure and repaired evidence remain separate.

12. Cleanup / rollback

  1. Confirm the follow-up GET returns 404 for the checkpoint record.
  2. Stop the specific loopback fixture with Ctrl+C.
  3. Keep results until review is complete.
  4. Delete only the disposable project directory if desired.
  5. If a test unexpectedly targeted anything other than loopback, stop and follow your environment's incident/data-cleanup process rather than attempting broad automated deletion.

Knowledge check

Why can the malformed-JSON checkpoint test legitimately end PASS?

The POST returns 201 but the follow-up GET returns the wrong name. Which layer failed?

What makes cleanup safe in this lab?

A CI run wants to log every Authorization header for debugging. What should you do?

What capability does Chapter 17 add to the Robot operating model?

13. Production operating model and Chapter 18 bridge

After Chapter 17, Robot can operate a browser layer and a service layer without confusing their state stores. Chapter 18 expands the same ownership discipline to databases, SSH, filesystem, processes, and infrastructure automation, where transaction/connection/process state must remain just as explicit.

Next lesson

Database, SSH, Filesystem, Process, and Infrastructure Automation Patterns: Core Concepts and Mental Model

Continue with Database, SSH, Filesystem, Process, and Infrastructure Automation Patterns: Core Concepts and Mental Model. It builds directly on the state, evidence, and operating assumptions established here, so carry those constraints forward rather than treating the next page as an isolated topic.

References and version anchors

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.