Skip to content

A module library that logs and fails

Chapter lab: Custom librariesch18-custom-libraries.zip · 4 KB

This chapter works in a prepared project. Download it before the first task; it unpacks into its own folder.

Download ch18-custom-libraries.zip

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

Terminal window
curl -fsSLO https://manykarim.github.io/robotframework-essentials-web/labs/ch18-custom-libraries.zip && unzip -q ch18-custom-libraries.zip && rm ch18-custom-libraries.zip

Open the folder in VS Code with code rfe-ch18-custom-libraries (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.

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

What's inside
  • Directoryrfe-ch18-custom-libraries/
    • Directory.vscode/
      • extensions.json
    • Directorychecks/
      • smoke.robot
    • Directorylibraries/
      • README.md
    • Directoryvariables/
      • README.md
    • .gitignore
    • .python-version
    • LAB.md
    • pyproject.toml
    • README.md
    • requirements.txt
    • uv.lock

A real keyword usually does three things: it computes a result and returns it, it logs what it did so the report is readable, and it fails clearly when something is wrong.

Robot Framework’s own logging is available to your library through robot.api.logger — logger.info(...) writes to log.html exactly like the built-in Log keyword. Returning a value hands it back to the suite; raising AssertionError fails the test with your message.

Task 1 — A module library with a builder and a check

Section titled “Task 1 — A module library with a builder and a check”
Edit

Goal: create libraries/order_lib.py with two functions — build_order_reference(prefix, number) that logs and returns a reference, and order_total_should_be_positive(total) that fails on a non-positive total.

Here is the same pair over a different domain — support tickets. Adapt it to orders (a four-digit reference, and a positive-total check).

Worked example — adapt it, don’t copy it

from robot.api import logger
def build_ticket_id(queue, number: int) -> str:
ticket = f"{queue}#{number:05d}"
logger.info(f"Opened ticket {ticket}")
return ticket
def priority_should_be_known(priority: str) -> None:
if priority not in {"low", "normal", "urgent"}:
raise AssertionError(f"Unknown priority: {priority}")

Done when

libraries/order_lib.py defines build_order_reference and order_total_should_be_positive.

Hint 1

Import the logger at the top: from robot.api import logger. In the builder, logger.info(...) before you return the reference.

Hint 2

The check keyword returns nothing and only raises on failure: if total <= 0: raise AssertionError(f"Order total must be positive, got {total}").

Solution
from robot.api import logger
def build_order_reference(prefix, number: int) -> str:
reference = f"{prefix}-{number:04d}"
logger.info(f"Built order reference {reference}")
return reference
def order_total_should_be_positive(total: float) -> None:
if total <= 0:
raise AssertionError(f"Order total must be positive, got {total}")
Run

Create checks/order_lib.robot:

*** Settings ***
Library ../libraries/order_lib.py
*** Test Cases ***
Reference Is Logged And Built
${ref}= Build Order Reference TRN 7
Should Be Equal ${ref} TRN-0007
Positive Total Passes
Order Total Should Be Positive 19.90

Run it, then open log.html to see your logger.info line:

Terminal window
uv run robot checks/order_lib.robot
Terminal window
robot checks/order_lib.robot
Terminal window
poetry run robot checks/order_lib.robot

Done when

the test Reference Is Logged And Built passes.

Check your understanding

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

  1. How does a Python library write to log.html?

    Show the answer

    Answer: from robot.api import logger then logger.info(...) — robot.api.logger writes to the log exactly like the built-in Log keyword.

  2. A module-based library is best when keywords…

    Show the answer

    Answer: stand alone (stateless) — Plain functions are perfect for stateless keywords; reach for a class when they must share state.

Key terms

robot.api.loggerconcept
Log from Python into log.html (logger.info/​debug/​warn).
module libraryconcept
A .py file of functions imported as keywords.

All terms in the glossary →