Chapter 10Lesson 02200–280 min

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.

Hands-onBranch traceLoop limitsExpected recoveryRefactoring

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?

What proves CONTINUE rather than a failed condition skipped the “skip” item?

Why should the invalid failure remain uncaught?

When should this control flow move to Python?

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.

Next lesson

IF/ELSE, FOR, WHILE, TRY/EXCEPT, BREAK, CONTINUE, and Control Flow: Configuration, Design Patterns, and Trade-Offs

Continue with IF/ELSE, FOR, WHILE, TRY/EXCEPT, BREAK, CONTINUE, and Control Flow: Configuration, Design Patterns, and Trade-Offs. 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.

Further reading

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.