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.
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=ciis observed when the command-line variable is supplied. -
RF_STAGE=integrationis 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?
ci, because the individual command-line variable
has higher startup priority.
Why should test C not see ${TEST_VALUE}?
The variable was created with test scope in test A; that scope ends when test A ends.
What is the root cause of the deliberate failure?
A suite-owned mutable list is changed in one test and reused by a later test, causing state contamination.
Would scope=GLOBAL be a valid repair for the list
failure?
No. It widens the shared state and makes ownership worse; isolate the mutable copy instead.
What does the preserved failing
output.xml contribute?
It provides first-failure evidence of the original execution state and failure hierarchy before the repair.
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.
Further reading
- Robot Framework 7.4.2 User Guide — Variables — scalar/list/dictionary/environment syntax, creation mechanisms, priorities, scopes, typed conversion, and Secret values.
- Robot Framework 7.4.2 User Guide — Variable priorities and scopes — static priority and runtime scope rules.
- Robot Framework 7.4.2 User Guide — VAR syntax — local/test/task/suite/suites/global scope configuration.
- Robot Framework 7.4.2 User Guide — Variable type conversion — stable typed variable creation introduced in 7.3.
- Robot Framework 7.4.2 User Guide — Secret variables — masking semantics and security limitations introduced in 7.4.
- Robot Framework Style Guide — casing and scope-oriented naming conventions.
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.