IF/ELSE, FOR, WHILE, TRY/EXCEPT, BREAK, CONTINUE, and Control Flow: Guided Hands-On Workflow
Build a disposable control-flow laboratory that progresses from IF to FOR, bounded WHILE, BREAK/CONTINUE, and TRY/EXCEPT while preserving branch traces and showing when logic should move behind named user keywords.
Learning objectives
- Implement IF/ELSE, FOR, bounded WHILE, BREAK, and CONTINUE with safe local values.
- Use TRY/EXCEPT with narrow error matching and prove unmatched failures still fail the test.
- Record branch/loop traces and iteration counts under the Robot output directory.
- Compare business-facing inline control logic with the same logic extracted into user keywords.
- Produce a small evidence packet showing caught versus uncaught failures and final status.
Current compatibility baseline. Verified
2026-08-31: Robot Framework 7.4.2 is the current stable release;
7.5b1 is a pre-release and is not required in this chapter. Native
IF/ELSE arrived in Robot Framework 4.0;
WHILE, TRY/EXCEPT, BREAK,
CONTINUE, and inline IF are available in
modern Robot Framework 5.0+ syntax. Robot Framework 7.4.2 gives
WHILE a default 10,000-iteration limit; production
examples here set a smaller explicit limit.
1. Scenario: classify and advance synthetic deployment states
The lab models a tiny deployment controller using only local
synthetic strings. No real deployment, API, browser, process, or
cloud target is touched. Inputs move through states such as
queued, warming, ready, and
invalid. Every control decision is appended to a trace
file under ${OUTPUT DIR}.
2. Project layout
rf10-control-lab/
├── suites/
│ └── control_flow.robot
└── evidence/
3. Complete progressive suite
*** Settings ***
Library OperatingSystem
*** Variables ***
${TRACE} ${OUTPUT DIR}/control-trace.txt
*** Test Cases ***
Progressive Native Control Flow
Create File ${TRACE} start\n
# IF/ELSE
VAR ${environment} staging
IF $environment == "production"
Trace prod-path
ELSE
Trace non-prod-path
END
# FOR + CONTINUE + BREAK
FOR ${item} IN queued skip warming ready ignored
IF $item == "skip"
Trace continue:${item}
CONTINUE
END
Trace inspect:${item}
IF $item == "ready"
Trace break:${item}
BREAK
END
END
# bounded WHILE
VAR ${attempt} ${0}
VAR ${state} warming
WHILE $state != "ready" limit=5
${attempt}= Evaluate $attempt + 1
${state}= Simulate State ${attempt}
Trace poll:${attempt}:${state}
END
Should Be Equal ${state} ready
# expected recovery
${result}= Normalize Synthetic State transient
Should Be Equal ${result} recovered
*** Keywords ***
Trace
[Arguments] ${message}
Append To File ${TRACE} ${message}\n ... encoding=UTF-8
Simulate State
[Arguments] ${attempt}
IF $attempt < 3
RETURN warming
END
RETURN ready
Normalize Synthetic State
[Arguments] ${raw}
TRY
Validate Synthetic State ${raw}
EXCEPT transient:* type=GLOB AS ${error}
Trace caught:${error}
RETURN recovered
ELSE
RETURN ${raw}
FINALLY
Trace normalize-finally:${raw}
END
Validate Synthetic State
[Arguments] ${raw}
IF $raw == "transient"
Fail transient: synthetic warming condition
ELSE IF $raw == "invalid"
Fail invalid: permanent synthetic configuration
END
4. Preflight and dry run
python --version
robot --version
robot --dryrun --outputdir evidence/dryrun suites/control_flow.robot
--dryrun validates parsing and keyword resolution but
does not exercise the actual branch outcomes or write the trace.
Record the exact Robot/Python versions before execution.
5. Run the normal workflow
robot --outputdir evidence/pass suites/control_flow.robot
Expected final status: PASS. In control-trace.txt,
inspect:skip should be absent because
CONTINUE runs first; items after
ready should be absent because BREAK exits
the FOR loop. The WHILE trace should show attempts 1–3 and then stop
because the state becomes ready, not because the limit
is hit.
6. Prove that recovery is narrow
Create a temporary diagnostic test that calls
Normalize Synthetic State invalid. The
EXCEPT transient:* branch must not match
invalid: permanent synthetic configuration. The test
should fail and preserve that original message.
Unmatched Failure Must Propagate
${result}= Normalize Synthetic State invalid
Log unreachable result=${result}
7. Safe expression evaluation with local values
Prefer $variable when the condition consumes arbitrary
strings or objects. The suite authors the expression itself; data
flows through variables. Do not construct an expression by
concatenating an environment variable, API field, form input, or
other untrusted string.
VAR ${label} O'Reilly
IF $label == "O'Reilly"
Log Quoted data is safe through $label.
END
8. Compare business-facing nesting with a named keyword
The following business-facing test is legal but too procedural:
*** Test Cases ***
Overloaded Test
FOR ${state} IN queued warming ready
IF $state == "ready"
Log deployment ready
BREAK
ELSE
Log waiting: ${state}
END
END
Prefer a domain keyword that exposes the outcome while keeping the loop implementation behind a name:
*** Test Cases ***
Readable Test
${final}= Find First Ready State queued warming ready
Should Be Equal ${final} ready
*** Keywords ***
Find First Ready State
[Arguments] @{states}
FOR ${state} IN @{states}
IF $state == "ready"
RETURN ${state}
END
END
Fail No ready state found
9. Expected evidence matrix
| Observation | What it proves |
|---|---|
| non-prod-path present | ELSE branch selected from a local string object |
| continue:skip present; inspect:skip absent | CONTINUE skipped remainder of current iteration |
| break:ready present; ignored absent | BREAK exited the FOR loop |
| poll:1/2/3 present; no poll:4 | WHILE ended because condition became false before limit |
| caught:transient... present | Expected error matched and was handled |
| normalize-finally:transient present | FINALLY executed after the matched failure |
| invalid diagnostic run FAIL | Unmatched failure propagated instead of being swallowed |
10. Small challenge
Extend Find First Ready State so states named
disabled are skipped with CONTINUE, but
fatal causes an immediate explicit failure. Predict the
trace and final result for disabled, warming, ready and
for warming, fatal, ready before running.
11. Knowledge check
Why is the WHILE loop limited even though the state is expected to become ready?
The expectation may be wrong because of a defect. A hard limit turns non-convergence into finite, diagnosable failure instead of an unbounded run.
What proves CONTINUE rather than a failed condition skipped the “skip” item?
The trace contains the continue marker and lacks later keywords from that same iteration while later iterations still execute.
Why should the invalid failure remain uncaught?
The handler contract covers only the expected transient condition. Catching invalid permanent configuration would hide a real defect.
When should this control flow move to Python?
When the logic becomes algorithmic, deeply nested, policy-heavy, or easier to unit-test as application/library code than as executable specification.
12. Summary and next step
You have implemented each native control family against synthetic data and verified the execution path from trace evidence. The important pattern is not syntax coverage; it is bounded decisions with transparent failure propagation. Lesson 3 turns these mechanisms into design choices and trade-offs.
Further reading
- Robot Framework 7.4.2 User Guide — control structures — FOR, WHILE, BREAK/CONTINUE, IF/ELSE, TRY/EXCEPT, and readability guidance.
-
Robot Framework 7.4.2 User Guide — WHILE loops
— expression evaluation, limits,
on_limit, and output-size considerations. -
Robot Framework 7.4.2 User Guide — TRY/EXCEPT
— exact/pattern matching,
AS,ELSE,FINALLY, and uncatchable failures. -
Robot Framework 7.4.2 User Guide — evaluating expressions
—
${var}replacement versus$varaccess and evaluation namespace behavior. - Robot Framework 7.4.2 BuiltIn — legacy-compatible conditional/loop-control helpers and native-syntax recommendations.
- Robot Framework project site — current stable release stream.
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.