Chapter 06Lesson 01120–160 min

Variables: Scalar, List, Dictionary, Environment, and Dynamic Values: Core Concepts and Mental Model

Model where Robot Framework variables come from, how priority and scope decide which value is visible, and why a value container is not the same thing as its ownership or lifetime.

Variable provenancePriorityScopeTyped valuesSecrets

Learning objectives

  • Trace a value from its source through priority resolution, scope, lookup, and use without treating every variable as global state.
  • Distinguish scalar access, list expansion, dictionary expansion, environment-variable syntax, and the underlying Python value each can carry.
  • Separate static sources such as Variable sections and command-line inputs from values created dynamically during execution.
  • Explain local, test/task, suite, suites, and global lifetimes and identify which scopes create cross-test coupling.
  • Recognize typed-variable and Secret semantics in Robot Framework 7.4.2, including what Secret does not protect.

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. The practical problem: a value is not just a name

Chapter 05 gave user keywords explicit argument and return contracts. The next question is where their values come from. In a small suite, ${URL}, ${count}, and ${user} can look like simple placeholders. In a production suite, the same logical setting may exist in a Variable section, an imported resource, a Python variable file, a command-line option, an environment variable, a keyword argument, and a runtime VAR. If you do not know which source owns the value and how long it lives, a green local run can become a confusing CI failure.

Robot variables therefore need three separate questions: what object is the value?, which definition wins?, and where is that value visible? Type, priority, and scope answer those questions respectively. None of them automatically answers whether the value is safe to log, mutable, or appropriate to share across workers.

Variable provenance and resolution flow
flowchart TD
A[Variable source] --> B[Priority / resolution]
B --> C[Visible scope]
C --> D[Scalar, list, dict, Secret or other object]
D --> E[Keyword argument / expression / assignment]
E --> F[Local Robot execution state]
G[Environment / CLI / variable file] --> A
H[Runtime VAR / keyword argument / return] --> B

2. Four sigils, two different ideas

The symbols $, @, &, and % are syntax, not a complete type system. ${items} can hold a Python list and pass that list as one object. @{items} expands a list-like value into multiple cells/arguments. &{config} expands a dictionary into named arguments or mapping items where supported. %{NAME} reads an operating-system environment variable and always starts as a string.

*** Variables ***
${SERVICE}          inventory
@{REGIONS}          eu-west    us-east
&{LIMITS}           retries=3    timeout=5

*** Test Cases ***
Container versus expansion
    Log    ${REGIONS}        # one Python list object
    Log Many    @{REGIONS}   # two separate arguments/items
    Log    ${LIMITS}[timeout]
    Log    %{RF_STAGE=local}

The scalar syntax is the general “give me the object” form. List and dictionary syntax are useful when expanding the container. The environment syntax is a lookup into process environment state, not a Robot suite variable definition.

3. Sources have different owners

Source Typical scope/ownership Key property
Keyword arguments / normal assignment Local Created for the current keyword/test body; disappears when local scope ends.
VAR default Local Explicit modern creation syntax; scope can be widened deliberately.
Variable section in suite Suite Static suite-owned configuration; available in that suite file.
Imported resource/variable file Suite Reusable static/dynamic configuration imported into the suite.
--variable / --variablefile Global Startup configuration visible to all executed suites; command-line values have high static priority.
%{ENV} Process environment String lookup owned by the process environment; defaults can be specified.
Built-in / automatic variables Global or context-specific Framework-provided values such as ${CURDIR} and execution-context variables.

4. Priority: “first wins” before execution, “last visible definition wins” at runtime

For values established before execution, Robot Framework gives command-line variables the highest priority. An individual --variable overrides a command-line --variablefile. A Variable section in a suite overrides imported resource/variable-file values with the same name. Among imported static sources, import order matters.

Runtime values are different. A local keyword argument can shadow a suite variable while that keyword runs. A test-scoped value can shadow the same-named suite value during the test. When that narrower scope ends, the outer value becomes visible again. This is why “the variable was overwritten” is often the wrong diagnosis: it may only have been shadowed.

Situation Visible value Reason
CLI -v STAGE:ci + suite ${STAGE}=local ci Command-line variable overrides static suite definition.
Suite ${MODE}=safe + keyword argument ${mode} argument value inside keyword Local argument shadows broader scope.
VAR ${MODE} experimental scope=TEST experimental for rest of test Dynamic test-scope definition becomes the visible value in that test.

5. Scope is lifetime and visibility, not importance

VAR defaults to LOCAL. Robot Framework 7.4.2 also supports TEST (or TASK), SUITE, SUITES, and GLOBAL. Broader scope should be an explicit design decision because it increases the number of callers that can observe or mutate the state.

*** Test Cases ***
Scope tracing
    VAR    ${local}      local
    VAR    ${TEST}       test-value      scope=TEST
    VAR    ${SUITE}      suite-value     scope=SUITE
    Log    ${local}
    Log    ${TEST}
    Log    ${SUITE}

A global value is not “better configuration.” It is simply visible more widely. In parallel execution, suite/global mutation can also become a concurrency hazard because different workers do not share one magical in-memory namespace and external shared state may still race.

6. Typed variables: conversion happens when the variable is created

Robot Framework 7.3 introduced variable type conversion. In 7.4.2, a declaration such as ${PORT: int} asks Robot to convert the created value to an integer. The annotation is part of variable creation; it is not a permanent runtime type guard applied every time the variable is later used.

*** Variables ***
${PORT: int}        8080
${RATIO: float}     0.75
@{CODES: int}       200    201    204

*** Test Cases ***
Typed creation
    VAR    ${attempts: int}    3
    Should Be Equal    ${PORT}        ${8080}
    Should Be Equal    ${attempts}    ${3}

This matters most when configuration arrives as text. A command-line or environment value may need deliberate conversion before numeric comparison or arithmetic.

7. Secret is log protection, not encryption

Robot Framework 7.4 added the Secret type. A Secret wraps a confidential value so Robot Framework can avoid exposing the real value in its own logs when the object is passed between compatible keywords. The real value still exists in memory and is available through APIs or .value. External libraries can also disclose it if they unwrap or log it incorrectly.

*** Variables ***
${TOKEN: Secret}    %{RF_DEMO_TOKEN=FAKE_LOCAL_TOKEN}

*** Test Cases ***
Pass without revealing
    Log    ${TOKEN}    # Robot representation is masked
    # Do not use ${TOKEN.value} in normal test data; that exposes the value.

Security boundary. A Secret is not encryption, a secret store, key rotation, access control, or transport protection. For real credentials, obtain the value from an appropriate secret source and pass the Secret only to libraries that document compatible handling.

8. Why this matters in DevOps

CI pipelines often promote the same suite through local, integration, staging, and ephemeral review environments. Reproducibility depends on knowing whether a value came from committed test data, a command-line profile, an environment variable, a variable file, or runtime mutation. Provenance also helps incident response: if a test unexpectedly targeted staging, you need evidence of which source produced that value without dumping credentials into logs.

A strong operating model therefore treats variable sources as configuration interfaces. It records non-sensitive effective settings, keeps secrets out of ordinary logs, minimizes shared mutation, and uses narrow scopes by default.

9. Knowledge check

Why can ${items} and @{items} refer to the same underlying list but behave differently?

A command-line --variable STAGE:ci and a suite Variable-section ${STAGE} local both exist. Which startup value wins?

Does Secret encrypt a credential?

Why prefer local or test scope over global mutation?

10. Summary and next step

Variables are values plus provenance, priority, and scope. Scalar/list/dictionary syntax determines how a value is passed; environment syntax reads process state; static and runtime definitions follow different resolution rules; typed creation can convert values; and Secret adds log masking without encryption. Lesson 2 turns this mental model into a controlled scope-tracing workflow.

Next lesson

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

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