Chapter 13Lesson 01180–240 min

Assertions, Error Handling, Expected Failures, and Recovery Patterns: Core Concepts and Mental Model

Build a truthful mental model of Robot Framework status propagation so hard failures, continuable failures, expected errors, skips, recovery, retries, teardowns, and final CI results are never conflated.

Failure semanticsAssertionsTRY/EXCEPTSKIPCI truth

Learning objectives

  • Trace an assertion or execution error from a keyword through test/task and suite status into result artifacts.
  • Distinguish hard failure, continuable failure, expected error, recovered error, skip, and retry as separate contracts.
  • Explain why a handled error can yield PASS while an ignored status can create a false green.
  • Identify which state belongs to Robot execution, test variables, external systems, credentials, and evidence artifacts.
  • Inspect version, selection, source, and existing results before changing failure behavior.

Current compatibility baseline. Verified 2026-08-31: Robot Framework 7.4.2 is the current stable release and requires Python 3.8+; 7.5b1 is a pre-release and is not required in this chapter. Native TRY/EXCEPT is the preferred modern error-handling surface. EXCEPT uses exact matching by default and supports type=GLOB, REGEXP, START, or LITERAL. BuiltIn Run Keyword And Expect Error defaults to glob matching. Continuable failures continue execution but still make the test fail. Skip/Skip If produce SKIP, and Wait Until Keyword Succeeds is a bounded retry helper for normal failures—not syntax errors, timeouts, or fatal execution-stopping errors.

1. The problem: green is meaningful only when failure semantics are explicit

Chapter 12 made imports deterministic. That makes the next question more important: when a keyword reports a problem, what status should the test have? A test that catches every error can be green while the system is broken. A negative test can be green for the wrong error. A “continue on failure” step can continue and still correctly leave the test red. A retry can eventually pass while hiding a recurring defect unless its attempts are preserved.

Robot Framework gives you several mechanisms because they express different intent. The production skill is not memorizing the keywords; it is choosing a status contract that tells CI and future readers the truth.

2. Read-only preflight before changing status behavior

python --version
python -m robot --version
python -m robot --dryrun --outputdir results/preflight tests

Record the interpreter/framework version, executed path, selected tests/tags, and any pre-existing output.xml/log.html/report.html. Dry-run can expose parse/import/keyword-resolution problems before runtime recovery logic is even relevant. Do not add an EXCEPT around a failure until you know which layer produced it.

3. Status propagation mental model

From keyword outcome to CI evidence
flowchart TD
A[Keyword call] --> B{Outcome}
B -->|PASS| P[Continue normally]
B -->|Hard FAIL| F[Stop normal body]
B -->|Continuable FAIL| C[Continue but record failure]
B -->|Expected / narrowly recovered| R[Recovery contract decides next step]
B -->|SKIP| S[Stop test body as skipped]
F --> T[Test teardown]
C --> T
R --> T
S --> T
P --> T
T --> X[Test status PASS / FAIL / SKIP]
X --> Y[Suite status]
Y --> Z[output.xml / log.html / report.html / process return code]

The first arrow is the keyword result. A normal failure stops the body; a continuable failure records failure but allows later work; an expected/recovered failure is only a PASS when the recovery contract positively proves the observed error was the one intended; a skip is neither PASS nor FAIL. Teardown is a cleanup/evidence phase, not a mechanism for erasing the original outcome. The final status feeds suite status and the runner return code used by CI.

4. Define the state owners before handling an error

State/evidence Owner Failure question
Keyword status and error message Current Robot keyword call Did this operation meet its contract?
Test/task status Current executable scenario Should this scenario count as PASS, FAIL, or SKIP?
Suite status Suite/result aggregation Did any test fail; did any pass; were all skipped?
Local/test/suite variables Robot scopes from Chapter 06 Did recovery mutate shared state that later steps consume?
Library/external-system state Imported library or system under automation Was partial work performed before failure?
Credential/trust boundary Environment/secret manager/external provider Could diagnostics expose sensitive values?
Evidence artifacts Execution output directory Was the first failure preserved before repair/retry?
CI worker/process return code Runner environment Will the pipeline see the truthful final status?

5. Six contracts that must not be collapsed

Contract Typical mechanism Final intent
Hard failure Should Be Equal, Fail, library assertion FAIL and stop normal body
Continuable failure Run Keyword And Continue On Failure or continuable exception/tag Continue collecting evidence, but final test remains FAIL
Expected negative outcome TRY/EXCEPT with narrow match or Run Keyword And Expect Error PASS only if the intended error occurred
Recovered technical condition Narrow TRY/EXCEPT plus explicit alternate path PASS only if recovery restores the declared contract
Skip Skip, Skip If, robot:skip SKIP; scenario is not evidence of success
Retry Wait Until Keyword Succeeds with bounded attempts/time PASS only if transient behavior is an explicit contract and final attempt succeeds

6. Assertions are evidence-producing contracts, not generic booleans

Prefer the assertion that states what is wrong. A containment failure should say which collection/string missed which item; a numeric comparison should use a numeric contract; a pattern should use an explicit pattern assertion. Generic equality is valuable when exact equality is the real requirement, but it should not become the only assertion because it can force the reader to reverse-engineer intent.

*** Test Cases ***
Precise assertions
    Should Contain    release-ready    ready
    Should Be Equal As Integers    42    42
    Should Match    artifact-2026.08    artifact-2026.*
    Should Be Equal    expected    expected    msg=Release state must match the approved fixture

7. Expected error is a positive assertion about the error contract

*** Keywords ***
Validate Amount
    [Arguments]    ${amount}
    IF    $amount < 0
        Fail    amount must be non-negative
    END

*** Test Cases ***
Negative amount is rejected
    ${message}=    Run Keyword And Expect Error
    ...    EQUALS:amount must be non-negative
    ...    Validate Amount    ${-1}
    Should Be Equal    ${message}    amount must be non-negative

The test passes because it proves the input was rejected for the exact intended reason. A broad * would also match unrelated failures and is therefore weaker evidence. Native TRY/EXCEPT is preferred for richer recovery; Run Keyword And Expect Error remains concise when the whole contract is simply “this keyword must fail with this error.”

8. TRY/EXCEPT: exact by default, patterns only when intentional

*** Test Cases ***
Recover one known technical condition
    TRY
        Fail    cache-not-ready: node-a
    EXCEPT    cache-not-ready:    type=START    AS    ${error}
        Log    Known disposable condition: ${error}
    END
    Log    Recovery path completed

In 7.4.2, a message on EXCEPT is an exact match unless type= changes it. GLOB, REGEXP, START, and LITERAL are explicit choices. A message-less EXCEPT catches ordinary errors broadly and should be rare in production tests because it can convert unknown defects into success. Syntax errors and errors that stop the whole execution are not catchable by native TRY/EXCEPT.

9. Continue-on-failure means “collect more evidence,” not “ignore the failure”

*** Test Cases ***
Collect two observations but remain failed
    Run Keyword And Continue On Failure    Should Be Equal    alpha    beta
    Log    This observation is still collected
    Should Be Equal    ${1}    ${1}

The second and third lines run, but the test is still FAIL because the first assertion was continuable—not successful. This is appropriate for independent diagnostics that are safe after a validation failure. It is inappropriate before destructive actions that assume the failed precondition was satisfied.

10. SKIP and retry answer different questions

SKIP says the scenario was not valid to execute or cannot currently provide pass/fail evidence. Retry says repeated attempts are part of a bounded transient-condition contract. Neither should be used to make an unstable test “look better.” A skipped test is visible as SKIP; a retried test should retain attempt evidence in log.html.

11. DevOps connection: status is an API consumed by CI

Robot's process return code is derived from final execution status. That means error handling is part of the delivery interface. If a helper turns a failed assertion into an unused Boolean, the pipeline may receive zero and deploy. If a test uses continuable failures, the pipeline remains red while diagnostics are richer. If a capability is unavailable and the test is legitimately skipped, reports distinguish “not executed” from “verified.”

12. Knowledge check

A continuable assertion fails, later keywords pass, and teardown passes. What is the test status?

What is the default matching mode for native EXCEPT with a message?

What is dangerous about Run Keyword And Return Status if the returned Boolean is ignored?

Is SKIP a weak form of PASS?

13. Summary and next step

You now have the status model: failures, recovery, continuation, skip, and retry are different contracts. Lesson 2 turns that model into a disposable suite where each mechanism is exercised with concrete result evidence and a deliberately false-green case.

Next lesson

Assertions, Error Handling, Expected Failures, and Recovery Patterns: Guided Hands-On Workflow

Continue with Assertions, Error Handling, Expected Failures, and Recovery Patterns: Guided Hands-On Workflow. 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.