Chapter 06Lesson 05180–240 min

Checkpoint Lab — Variables: Scalar, List, Dictionary, Environment, and Dynamic Values

Build and audit a scope-tracing suite, predict precedence across local/test/suite/environment/CLI inputs, then repair a deliberately shared mutable container without losing first-failure evidence.

Checkpoint labPrecedence matrixScope transitionsShared stateEvidence

Learning objectives

  • Build a disposable project whose variable sources and scopes can be observed independently.
  • Predict effective values before execution and compare predictions with console/output evidence.
  • Demonstrate local, test, suite, environment, and command-line ownership without using real secrets.
  • Capture and diagnose one deliberate shared-list contamination failure before repairing it.
  • Produce a small variable-governance checklist suitable for future CI and parallel execution.

Current compatibility baseline. Verified 2026-08-31: Robot Framework 7.4.2 is the stable release used by this chapter and requires Python 3.8+. Robot Framework 7.5b1 is a pre-release and is not required. Native VAR has existed since 7.0; scope=SUITES since 7.1; variable type conversion such as ${count: int} is stable since 7.3; and Secret variables are stable since 7.4.

1. Scenario and acceptance criteria

You are preparing a tiny automation project for promotion through CI. The same logical configuration has defaults, environment input, and a command-line override. One test also creates local/test/suite runtime values. A separate mutable list is deliberately shared so the second test fails. Your job is to predict each result, preserve evidence, repair only the faulty ownership boundary, and prove the final run.

Safety boundary. Use only values such as local, integration, ci, and FAKE_ONLY. Do not use production URLs, real credentials, personal tokens, or shared filesystem locations.

2. Create the disposable layout

rf06-checkpoint/
├── suites/
│   └── variables.robot
├── evidence/
│   ├── failing/
│   └── repaired/
└── notes/
    └── predictions.md

Preflight: record python --version and python -m robot --version. Expected Robot Framework version for this chapter is 7.4.2.

3. Build the first (intentionally flawed) suite

The suite below combines static configuration, environment lookup, CLI override, runtime scopes, typed creation, and one deliberate mutable shared-state defect.

*** Settings ***
Library    Collections

*** Variables ***
${STAGE}               file-default
${WORKERS: int}        2
@{BASE_ITEMS}          alpha    beta

*** Test Cases ***
A - Trace Sources And Scopes
    Log To Console    ROBOT_STAGE=${STAGE}
    Log To Console    ENV_STAGE=%{RF_STAGE=env-default}
    VAR    ${local}        local-value
    VAR    ${TEST_VALUE}   test-value      scope=TEST
    VAR    ${SUITE_VALUE}  suite-value     scope=SUITE
    VAR    ${workers: int}    %{RF_WORKERS=3}
    Should Be Equal    ${workers}    ${3}
    Called Keyword Sees Test Scope

B - Mutate Shared Baseline
    Append To List    ${BASE_ITEMS}    gamma
    Should Contain    ${BASE_ITEMS}    gamma

C - Baseline Should Still Be Clean
    Should Be Equal    ${BASE_ITEMS}    ${{['alpha', 'beta']}}
    Should Be Equal    ${SUITE_VALUE}    suite-value
    Variable Should Not Exist    ${TEST_VALUE}

*** Keywords ***
Called Keyword Sees Test Scope
    Should Be Equal    ${TEST_VALUE}    test-value

4. Predict before running

Observation Prediction Reason
${STAGE} with -v STAGE:ci ci CLI variable overrides suite Variable section.
%{RF_STAGE} when environment is integration integration Direct process-environment lookup.
${TEST_VALUE} inside called keyword test-value Test scope includes called keywords.
${TEST_VALUE} in test C does not exist Test scope ended after test A.
${SUITE_VALUE} in test C suite-value Suite scope persists in same suite.
Test C baseline assertion FAIL Test B mutated the suite-owned list object.

5. Execute and preserve first-failure evidence

Set only synthetic environment values. Use separate output directories so the failing run cannot be overwritten by the repaired run.

# Bash / Git Bash
RF_STAGE=integration RF_WORKERS=3 python -m robot   --variable STAGE:ci   --outputdir evidence/failing   suites/variables.robot

# PowerShell
$env:RF_STAGE = "integration"
$env:RF_WORKERS = "3"
python -m robot --variable STAGE:ci --outputdir evidence/failing suites/variables.robot

Expected overall status: failure caused by test C. Do not delete evidence/failing/output.xml, log.html, or report.html. Those artifacts prove the original shared-state defect.

6. Diagnose the failure at the correct layer

The failing assertion is not a variable-priority issue: CLI/env resolution already produced the expected values. It is not a timing issue: no asynchronous system exists. It is not a library import issue: Collections loaded and mutation succeeded. The defect is object ownership: ${BASE_ITEMS} is suite-owned mutable state and test B changed it for later tests.

Write this classification into notes/predictions.md along with the exact failing assertion and source line. That creates a durable explanation rather than a “fixed by retry” anecdote.

7. Repair with per-test isolation

Keep the suite baseline unchanged and copy before mutation.

B - Mutate Local Copy
    ${items}=    Copy List    ${BASE_ITEMS}
    Append To List    ${items}    gamma
    Should Contain    ${items}    gamma
    Should Be Equal    ${BASE_ITEMS}    ${{['alpha', 'beta']}}

Now run to a new output directory:

# Use the same synthetic RF_STAGE/RF_WORKERS environment values.
python -m robot   --variable STAGE:ci   --outputdir evidence/repaired   suites/variables.robot

Expected result: all tests pass, while the failing evidence remains available for comparison.

8. Required evidence packet

Artifact What it proves
Version output Pinned framework/interpreter context.
Predictions matrix Expected source winners and scope lifetimes before execution.
Failing output.xml/log.html/report.html First-failure state and call hierarchy.
Repaired result artifacts Correction works without deleting original evidence.
Console effective-value lines Non-sensitive CLI/environment resolution.
Before/after suite diff Only ownership of mutable test data changed.

9. Verification checklist

  • The ZIP/project contains no real secrets or production targets.
  • STAGE=ci is observed when the command-line variable is supplied.
  • RF_STAGE=integration is observed through environment syntax.
  • The test-scoped value is visible to a called keyword but absent in the later test.
  • The suite-scoped value remains available to the later test.
  • The first run fails because the suite list was mutated.
  • The repaired run passes using a local copy.
  • The failing evidence remains preserved after the repair.

10. Cleanup / rollback

Delete only the disposable rf06-checkpoint directory when you no longer need the evidence. Clear the synthetic shell variables if they were set persistently in your current shell. Do not add cleanup that edits user/global environment settings, external services, or shared CI configuration.

11. Production variable-governance checklist

  • Document startup configuration sources and intended override order.
  • Default to local/test scope; justify suite/global mutation in review.
  • Convert external strings at the boundary where semantic typing begins.
  • Copy mutable fixtures before test-specific mutation.
  • Keep real secrets outside committed suite data and use Secret only as one masking layer.
  • Capture non-sensitive effective configuration in CI evidence.
  • Do not rely on working-directory accidents for variable-file paths.

12. Knowledge check

The suite file says ${STAGE}=file-default, but the run uses -v STAGE:ci. Which value should test A print?

Why should test C not see ${TEST_VALUE}?

What is the root cause of the deliberate failure?

Would scope=GLOBAL be a valid repair for the list failure?

What does the preserved failing output.xml contribute?

13. Chapter checkpoint and bridge

You can now reason about variables as a configuration and state system rather than a bag of placeholders. You traced static priority, environment/CLI inputs, local/test/suite lifetimes, typed values, Secret boundaries, and mutable-object ownership, then preserved and repaired a real shared-state failure. Chapter 07 builds on this foundation by examining the always-available BuiltIn library and how keyword status, assertions, logging, conversion, and control behavior propagate through execution.

Next lesson

BuiltIn Library and Core Execution Semantics: Core Concepts and Mental Model

Continue with BuiltIn Library and Core Execution Semantics: Core Concepts and Mental Model. 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.