Chapter 06Lesson 02150–200 min

Variables: Scalar, List, Dictionary, Environment, and Dynamic Values: Guided Hands-On Workflow

Build a disposable scope laboratory that creates containers, consumes environment and CLI inputs, uses typed VAR values, and proves exactly which value is visible at each point.

Hands-onVAREnvironmentCLI variablesScope trace

Learning objectives

  • Create scalar, list, and dictionary values and explain when to use scalar access versus expansion.
  • Consume an environment variable with a safe default and compare it with a Robot command-line variable.
  • Use VAR with local, test, and suite scope and observe lifetime boundaries without depending on global mutation.
  • Capture non-sensitive evidence showing resolved values, scope transitions, and output artifacts.
  • Use typed variable creation for numeric data while keeping environment/CLI ownership explicit.

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. Lab setup and preflight

Create a disposable directory named rf06-variables-lab inside an isolated Robot Framework 7.4.2 environment. The lab needs no external service, browser, database, SSH host, container, or paid platform. Use only synthetic values.

rf06-variables-lab/
├── suites/
│   └── scope_lab.robot
└── results/

Preflight:
python --version
python -m robot --version

Expected baseline: Python 3.8+ and Robot Framework 7.4.2. Keep the output directory explicit so evidence does not mix with results from earlier chapters.

2. Build the suite in layers

The first version defines static containers and a suite default. It also reads an environment value using a harmless fallback. Notice that the environment lookup remains a string source.

*** Settings ***
Documentation    Chapter 06 variable scope laboratory.

*** Variables ***
${STAGE}              file-default
${RETRIES: int}       2
@{REGIONS}            eu-west    us-east
&{LIMITS}             timeout=5    workers=2

*** Test Cases ***
Inspect Static Inputs
    Log To Console    STAGE=${STAGE}
    Log To Console    RETRIES=${RETRIES}
    Log To Console    REGIONS=${REGIONS}
    Log To Console    TIMEOUT=${LIMITS}[timeout]
    Log To Console    ENV_STAGE=%{RF_STAGE=env-default}

Before running, predict five values. The typed ${RETRIES: int} becomes an integer, but the dictionary values in this simple declaration are strings unless separately converted.

3. Run with no overrides, then with environment input

Use an explicit output directory. Shell syntax differs; the environment assignment itself is outside Robot Framework.

# Bash / Git Bash
RF_STAGE=integration python -m robot --outputdir results/env suites/scope_lab.robot

# PowerShell
$env:RF_STAGE = "integration"
python -m robot --outputdir results/env suites/scope_lab.robot

Expected console evidence includes STAGE=file-default and ENV_STAGE=integration. The environment variable did not override ${STAGE} because %{RF_STAGE} is a distinct lookup; names that look similar are not automatically merged.

4. Add a Robot command-line variable

Now introduce a startup override with the same Robot variable name as the suite Variable section.

python -m robot   --variable STAGE:ci   --outputdir results/cli   suites/scope_lab.robot

Expected evidence: STAGE=ci. The command-line variable has higher startup priority than the suite Variable section. This is a useful configuration boundary for CI, but avoid passing real secrets directly in command histories.

5. Trace dynamic scopes with VAR

Add two tests. The first creates test- and suite-scoped values; the second proves which state survives.

*** Test Cases ***
Create Runtime Scopes
    VAR    ${local}       local-value
    VAR    ${TEST_VAL}    test-value     scope=TEST
    VAR    ${SUITE_VAL}   suite-value    scope=SUITE
    Log To Console    LOCAL=${local}
    Log To Console    TEST=${TEST_VAL}
    Log To Console    SUITE=${SUITE_VAL}
    Keyword Sees Test And Suite

Observe Next Test
    Variable Should Not Exist    ${local}
    Variable Should Not Exist    ${TEST_VAL}
    Should Be Equal    ${SUITE_VAL}    suite-value

*** Keywords ***
Keyword Sees Test And Suite
    Should Be Equal    ${TEST_VAL}     test-value
    Should Be Equal    ${SUITE_VAL}    suite-value

The local value belongs to the current test body. The test-scoped value is visible to keywords called by that test but disappears before the next test. The suite-scoped value remains visible to later tests in the same suite.

6. Typed runtime input

Environment variables and individual CLI variables originate as text. Convert at the boundary where a typed value becomes meaningful.

*** Test Cases ***
Typed Boundary
    VAR    ${workers: int}    %{RF_WORKERS=2}
    Should Be Equal    ${workers}    ${2}
    Should Be True    $workers >= 1

If RF_WORKERS=two, creation fails instead of silently pretending the value is an integer. That is useful configuration evidence: the failure identifies the boundary where an invalid external string entered the suite.

7. Optional safe Secret demonstration

Use only a fake token. The point is to inspect masking behavior without introducing a real credential.

*** Variables ***
${DEMO_TOKEN: Secret}    %{RF_DEMO_TOKEN=FAKE_ONLY}

*** Test Cases ***
Secret Representation
    Log    ${DEMO_TOKEN}
    Log To Console    Secret object is present; do not print .value

Do not add an exercise that logs ${DEMO_TOKEN.value}. That would deliberately defeat the protection being taught.

8. Evidence packet

Keep the following non-sensitive evidence:

  • python --version and python -m robot --version.
  • The exact command lines for the default, environment, and CLI runs.
  • Console lines showing effective non-sensitive values.
  • results/*/output.xml, log.html, and report.html.
  • A small variable-source matrix recording source, scope, and expected winner.
Logical setting Candidate sources Expected winner / observation
STAGE Variable section + -v STAGE:ci CLI value ci
RF_STAGE Process environment + default Environment if present; otherwise env-default
TEST_VAL VAR scope=TEST Visible only during creating test and its called keywords
SUITE_VAL VAR scope=SUITE Visible to later tests in same suite

9. Challenge: choose the right owner

You need three values: a per-keyword temporary normalized username, a test correlation ID used by several keywords, and an environment name chosen by CI. Decide the source/scope before coding.

A strong answer uses local scope for the normalized username, test scope for the correlation ID, and a command-line/environment configuration boundary for the environment name. It does not use one global variable simply because all three values are “configuration.”

10. Knowledge check

Why did -v STAGE:ci override the suite Variable section?

Why can a keyword called by a test see a scope=TEST VAR?

What should happen when ${workers: int} is created from the string two?

Why is %{RF_STAGE} not automatically the same as ${STAGE}?

11. Summary and next step

You have now observed static priority, environment lookup, command-line overrides, local/test/suite lifetime, and typed creation using only disposable data. Lesson 3 turns those mechanics into design decisions for configuration files, mutation, naming, and parallel-safe suites.

Next lesson

Variables: Scalar, List, Dictionary, Environment, and Dynamic Values: Configuration, Design Patterns, and Trade-Offs

Continue with Variables: Scalar, List, Dictionary, Environment, and Dynamic Values: 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.