Skip to content

POST and error contracts

Chapter lab: API foundationsch11-api-foundations.zip · 17 KB

This lesson continues in the same lab as the lesson before it. If you don’t have it yet, download it here.

Download ch11-api-foundations.zip

Or fetch and unpack it from a terminal in VS Code:

Terminal window
curl -fsSLO https://manykarim.github.io/robotframework-essentials-web/labs/ch11-api-foundations.zip && unzip -q ch11-api-foundations.zip && rm ch11-api-foundations.zip

Open the folder in VS Code with code rfe-ch11-api-foundations (or File → Open Folder…) and accept the recommended RobotCode and Python extensions. Then set it up:

Terminal window
uv sync
Terminal window
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Keep the environment active in every terminal where you run lesson commands.

Terminal window
poetry install --no-root

Python 3.13 or newer is required; uv installs it when it is missing.

Also needed for this lab

Start the RF Demo Shop in its own terminal and keep it running while you work:

Terminal window
uv run python demo_app/serve.py
Terminal window
python demo_app/serve.py
Terminal window
poetry run python demo_app/serve.py

Open in browserNo setup? Try the lab right here: its files, an editor and a terminal, running in your browser.

What's inside
  • Directoryrfe-ch11-api-foundations/
    • Directory.vscode/
      • extensions.json
    • Directorychecks/
      • smoke.robot
    • Directorydemo_app/
      • api.py
      • serve.py
      • store.py
      • web.py
    • Directoryresources/
      • api.resource
    • .gitignore
    • .python-version
    • LAB.md
    • pyproject.toml
    • README.md
    • requirements.txt
    • uv.lock

A contract has two sides: the success case and the failure case. POST creates a resource — send a dictionary as JSON with json=${body}. And a good API test also asserts the error contract: a missing product should return 404, not a surprise.

Use expected_status=404 so the request keyword treats the 404 as expected instead of failing.

Task 1 — POST an order and assert a 404 for a missing product

Section titled “Task 1 — POST an order and assert a 404 for a missing product”
Edit

Goal: create checks/post.robot with two tests — one that POSTs an order and asserts a 201, and one that GETs a missing product and asserts a 404.

Here is the same success-and-failure pair over different data. Adapt it.

Worked example — adapt it, don’t copy it

*** Settings ***
Library RequestsLibrary
Resource ../resources/api.resource
*** Test Cases ***
Ordering A Backpack Returns 201
${body}= Create Dictionary product=trail-backpack quantity=1
${resp}= POST ${API_URL}/api/orders json=${body}
Status Should Be 201 ${resp}
Should Be Equal ${resp.json()}[status] complete
Missing Product Is A 404
${resp}= GET ${API_URL}/api/products/ghost expected_status=404
Should Be Equal ${resp.json()}[error] product not found

Done when

both tests are defined.

Hint 1

Build the order body with Create Dictionary product=travel-mug quantity=2, then POST ${API_URL}/api/orders json=${body} and assert 201.

Hint 2

For the error test, pass expected_status=404 on the GET so the keyword accepts it, then assert Should Be Equal ${resp.json()}[error] product not found.

Solution
*** Settings ***
Library RequestsLibrary
Resource ../resources/api.resource
*** Test Cases ***
Placing An Order Returns 201
${body}= Create Dictionary product=travel-mug quantity=2
${resp}= POST ${API_URL}/api/orders json=${body}
Status Should Be 201 ${resp}
Should Be Equal ${resp.json()}[status] complete
Unknown Product Is A 404
${resp}= GET ${API_URL}/api/products/nope expected_status=404
Should Be Equal ${resp.json()}[error] product not found
Run

Run:

Terminal window
uv run robot checks
Terminal window
robot checks
Terminal window
poetry run robot checks

Done when

the order posts with 201, and the missing product returns 404.

Check your understanding

Quick recall. Your first answer stays in this browser; the quiz never blocks your progress.

  1. How do you send a JSON body with POST?

    Show the answer

    Answer: POST url json=${dict} — POST ${API_URL}/api/orders json=${body} sends a dictionary as a JSON body.

  2. To assert a 404 without failing the request, use…

    Show the answer

    Answer: GET url expected_status=404 — expected_status=404 tells RequestsLibrary the 404 is expected, so the keyword doesn't fail.

Key terms

POSTkeyword
POST url json=${dict} — create a resource.
expected_statusconcept
Assert a non-2xx status is expected, e.g. GET url expected_status=404.

All terms in the glossary →