Robot Framework Foundations, ATDD, BDD, RPA, and Use Cases: Guided Hands-On Workflow
Trace a harmless Robot Framework workflow from source text through keyword execution into output.xml, log.html, and report.html, while comparing tests, tasks, and a lower-level check.
Learning objectives
- Inspect a tiny suite before execution and predict its state changes.
- Run Robot with an explicit output directory and identify generated artifacts.
- Trace a BuiltIn keyword call from source through PASS/FAIL evidence.
- Compare the same requirement as a Robot test, Robot task, and lower-level Python assertion.
- Build a small, reproducible evidence packet using only local synthetic data.
Lab baseline. Use a disposable directory and Robot Framework 7.4.2 on Python 3.8+. This lesson uses BuiltIn only. No browser, API, database, SSH server, external account, or paid service is required.
1. The workflow you will trace
The goal is not to memorize syntax. The goal is to observe causality: source text becomes an execution model; a test calls a keyword; the keyword returns or fails; Robot records the result; files appear in an output directory. We will keep the automated domain intentionally tiny so every state transition is visible.
sequenceDiagram participant S as readiness.robot participant R as Robot core participant B as BuiltIn participant V as Synthetic values participant O as Result artifacts S->>R: Parse suite and test R->>B: Should Be Equal(status, expected) B->>V: Read argument values V-->>B: ready, ready B-->>R: PASS R->>O: Record test + keyword status O-->>S: output.xml / log.html / report.html
2. Preflight: prove what will execute
Chapter 02 will build an isolated Python environment carefully. For
this guided chapter, do not silently trust whichever
robot command happens to be first on PATH.
Record the interpreter and framework identity that will execute the
suite.
python --version
python -m robot --version
python -m pip show robotframework
Expected baseline for the examples in this lesson is Robot Framework 7.4.2 and Python 3.8 or newer. If your machine differs, either create a disposable environment pinned to 7.4.2 or treat the command/output examples as version-scoped and verify your installed documentation before copying details.
3. Inspect the suite before running it
*** Settings ***
Documentation Safe local Chapter 01 workflow.
*** Variables ***
${CANDIDATE} build-142
${STATUS} ready
${EXPECTED} ready
*** Test Cases ***
Release Candidate Is Ready
[Documentation] Verify synthetic readiness without external systems.
Log Candidate=${CANDIDATE}
Should Be Equal ${STATUS} ${EXPECTED}
There are four important source-level facts. First, the file is a
suite because it contains a test case section. Second, the values in
the Variables section are suite variables available to the test.
Third, Log and Should Be Equal come from
BuiltIn, which is automatically available. Fourth, no keyword
crosses into an external system, so the only durable mutation caused
by the run should be result files.
4. Run once with an explicit artifact directory
mkdir -p results
python -m robot --outputdir results readiness.robot
On PowerShell, creating the directory first is optional because Robot can create the output directory, but an explicit path keeps the workflow visible:
New-Item -ItemType Directory -Force results | Out-Null
python -m robot --outputdir results readiness.robot
The exact timestamps and elapsed time vary. The invariant
observations are one suite, one test, a PASS status when
ready == ready, and generated results under
results/.
| Before run | Action | After run | Owner |
|---|---|---|---|
readiness.robot exists;
results/ empty or absent
|
Robot parses source | In-memory suite/test model exists | Robot core |
${STATUS}=ready |
Should Be Equal receives arguments |
Values remain unchanged; keyword gets PASS | BuiltIn + Robot result model |
| No result files for this run | Execution finishes |
output.xml, log.html,
report.html
|
Robot output directory |
5. Trace one call into the result model
Open log.html. Expand
Release Candidate Is Ready and then the
Should Be Equal keyword. The log should show the nested
execution detail and PASS status. In output.xml, the
structure is machine-readable. The following is intentionally
abridged: exact attributes, IDs, and timestamps can vary by Robot
version.
<robot generator="Robot 7.4.2 ..." ...>
<suite name="Readiness" ...>
<test name="Release Candidate Is Ready" ...>
<kw name="Should Be Equal" owner="BuiltIn" ...>
... arguments and messages ...
<status status="PASS" .../>
</kw>
<status status="PASS" .../>
</test>
</suite>
</robot>
The important relationship is not the precise XML attribute order. It is that keyword status rolls into test status, the test belongs to a suite, and the structured output can later be consumed by Rebot or external tooling.
6. Express one requirement three ways
A. As a Robot test
*** Variables ***
${STATUS} ready
*** Test Cases ***
Release Candidate Satisfies Readiness Rule
Should Be Equal ${STATUS} ready
This is a verification. The expected product is a trustworthy pass/fail result.
B. As a Robot task
*** Variables ***
${CANDIDATE} build-142
*** Tasks ***
Prepare Synthetic Handoff Message
Log Candidate ${CANDIDATE} would be prepared for handoff. console=True
This is an operational intent expressed with task terminology. It deliberately changes no external system. A real RPA task might move files, submit forms, or call systems through libraries; those side effects would have their own lifecycle and safety requirements.
C. As a lower-level Python check
status = "ready"
assert status == "ready"
The Python assertion is the smallest tool for this trivial condition. Robot adds value when the requirement benefits from named suites, keyword composition, readable acceptance language, cross-technology orchestration, standardized result artifacts, or non-programmer-readable specifications. Do not choose Robot merely because it can express the same comparison.
7. Trace BDD wording without inventing a second engine
*** Variables ***
${STATUS} ready
*** Test Cases ***
Candidate Can Proceed
Given candidate status is ready
When readiness is evaluated
Then candidate may proceed
*** Keywords ***
Candidate status is ready
Should Be Equal ${STATUS} ready
Readiness is evaluated
Log Evaluating synthetic readiness
Candidate may proceed
Should Be Equal ${STATUS} ready
During matching, Robot can remove the BDD prefix and resolve the remainder to a keyword. The user keyword then calls BuiltIn. In the log, you can see the higher-level business step and the lower-level assertion. That layered trace is one reason Robot can bridge readable acceptance intent and technical evidence.
8. Challenge — choose the right layer
You need to verify that a pure Python function returns
42 for one input, automate a browser-based approval
workflow, and create a nightly operational task that compiles a
synthetic status summary. Which should be a low-level unit test,
which should use a browser library behind Robot keywords, and which
is naturally a Robot task? Write your decision before revealing the
answer in the knowledge check.
9. Guided lab — evidence packet
- Create
readiness.robotusing Section 3. - Run it into
results/test/. -
Create
handoff.robotusing the task from Section 6. -
Run it into
results/task/so the second run cannot overwrite the first run's evidence. - Capture the command lines, framework/Python versions, console status, and directory tree.
- Open both logs and identify the different test/task terminology.
- Write a one-paragraph boundary statement: what Robot core did, what BuiltIn did, and what external systems were intentionally not involved.
Cleanup: delete only the disposable lab directory after you have reviewed the result files. The result directories are evidence, so deleting them before diagnosis would destroy useful information.
10. Knowledge check
Why use different output directories for the test run and task run?
To preserve each run's original evidence instead of overwriting files with the same default names.
Which layer owns ${STATUS} in the BuiltIn-only
suite?
It is Robot Framework variable state with suite scope. BuiltIn receives the value as an argument but does not own the variable definition.
Would a browser click belong to Robot core?
No. Robot resolves and executes a keyword, but a browser automation library owns the browser-facing implementation and browser session state.
Why might a pure Python assertion be better than Robot for a tiny function?
It is a lower-level, tightly scoped verification where Robot's orchestration/readability/result-model overhead may add little value. Use the smallest appropriate test layer.
11. Summary and next step
You traced a Robot run from source to parser/model, keyword resolution, BuiltIn execution, PASS/FAIL status, and durable artifacts. You also separated tests from tasks and compared Robot with a lower-level assertion. Lesson 3 uses this evidence model to choose among specification styles, keyword abstraction levels, and automation layers instead of treating Robot Framework as a universal hammer.
Further reading and current primary references
Version-sensitive statements in this lesson were checked on 2026-08-30. The mandatory path uses Robot Framework 7.4.2, the current stable release at the time of authoring. Robot Framework 7.5b1 is a pre-release and is not required here. Re-check these sources before pinning versions in a new environment.
- Robot Framework 7.4.2 User Guide
- BuiltIn library 7.4.2 documentation
- RFCP syllabus — purpose and use cases
- RFCP syllabus — architecture of Robot Framework
- RFCP syllabus — basic syntax and structure
- RFCP syllabus — keyword-driven, behavior-driven, and data-driven styles
- Robot Framework releases
- Robot Framework on PyPI
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.