Data-Driven Testing, Templates, Embedded Arguments, and Variants: Core Concepts and Mental Model
Learn how Robot Framework represents repeated business scenarios as explicit data variants, and separate test identity, template iterations, embedded keyword arguments, and result evidence before choosing a data-driven style.
Learning objectives
- Explain when repeated scenarios are data variation rather than separate workflows.
- Distinguish a named templated test from multiple iterations inside one templated test.
- Trace scenario intent through a template keyword to arguments, status, and result evidence.
- Explain what embedded arguments change in keyword readability and matching.
- Keep test data, Robot state, external-system state, and result artifacts as separate ownership boundaries.
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. In 7.4.2, templates can use normal, named, and embedded arguments. A templated test containing multiple data rows executes all rows even when one fails or is skipped, then aggregates the test status. User-keyword argument type conversion is stable from Robot Framework 7.3.
1. The problem: repetition can hide either data or behavior
By Chapter 10 you can branch and loop, but control flow is not the right answer to every repeated scenario. If five cases execute the same contract with different inputs, copying the same steps five times creates maintenance drift. Hiding all five cases inside one loop removes useful test identity. Data-driven design asks a more precise question: what behavior stays invariant, and what input/output values vary?
A template is useful only when the invariant part is strong enough to name as one keyword contract. If the rows need different setups, different workflows, or unrelated assertions, they are probably not one data-driven scenario.
2. Inspect before authoring variants
Before changing suite structure, prove which interpreter/framework and files you are about to use. These commands do not mutate the system under test:
python --version
python -m robot --version
python -m robot --dryrun --outputdir evidence/dryrun suites/variants.robot
--dryrun validates parsing, imports, keyword
resolution, and argument compatibility without executing normal
keywords. It does not prove runtime behavior, but it is useful for
separating model errors from scenario failures.
3. Define the objects and owners first
| Object | What it owns | What it does not own |
|---|---|---|
| Test/task name | Selectable scenario identity and report row | A template iteration is not automatically a separate test |
| Template keyword | Invariant workflow/assertion contract | Variant values or CI environment configuration |
| Data row | Arguments for one template invocation/variant | Library instance state or external durable state |
| Embedded argument | A value captured from the keyword call name | A new execution engine or BDD runtime |
| Robot variable scope | Local/test/suite/global value visibility | Browser/API/database/process state |
| External state | State owned by the system/library being automated | Robot report identity |
| Result artifacts |
output.xml, log.html,
report.html
|
The source-of-truth business data itself |
| Credential boundary | Secret source and disclosure policy | A data table is never a secret store |
4. Mental model: intent becomes repeated calls, not repeated engines
flowchart TD A[Scenario intent] --> B[Template or user keyword contract] B --> C[Variant row / embedded arguments] C --> D[Template keyword invocation] D --> E[BuiltIn / library / external action] E --> F[Assertion or returned classification] F --> G[Iteration status] G --> H[Test status] H --> I[output.xml / log.html / report.html]
The first arrow is a design decision: decide that the behavior is one contract. The row supplies only the values that vary. Robot resolves the template keyword exactly as it resolves other keywords. The keyword may call BuiltIn, standard libraries, user keywords, or later external libraries. Each invocation produces status evidence. With a multi-row templated test, those iteration outcomes are aggregated into one test result; with separate named tests using a suite-level template, each test keeps its own report identity.
5. Two shapes that look similar but have different result identity
Shape A — one named test per variant. A suite-level
Test Template lets each test case name carry business
identity while the remaining cells provide arguments:
*** Settings ***
Test Template Identifier Should Have Classification
*** Test Cases *** CANDIDATE EXPECTED
Minimum valid abc ACCEPT
Too short ab REJECT
Contains punctuation ab-c REJECT
Robot reports three tests. Each can be selected/rerun by its test name.
Shape B — multiple iterations inside one test. Here one test contains several rows:
*** Test Cases ***
Grouped identifier variants
[Template] Identifier Should Have Classification
abc ACCEPT
ab REJECT
ab-c REJECT
Robot reports one test named
Grouped identifier variants. All rows execute even if
one fails. The log shows the individual template calls, but the
report/selectable test identity remains the single test. This
distinction is central to diagnosable CI design.
6. Multiple template iterations deliberately continue
Robot Framework 7.4.2 automatically continues through the top-level iterations of a templated test. If any iteration fails, the aggregate test is FAIL. If none fail and at least one passes, it is PASS. If every iteration is skipped, it is SKIP. This continuation is not a blanket instruction to ignore failures inside helper keywords; it exists so the data matrix can produce complete row-level evidence.
Do not confuse coverage with isolation. Multiple rows in one templated test share the same test lifecycle and test-scoped variables. If each variant needs independent setup/teardown, ownership, or rerun identity, use separate tests rather than packing rows into one test.
7. Embedded arguments make the keyword call read like the case
Embedded arguments place variables in a user keyword name. With templates, the placeholders in the template name are replaced by row values before Robot invokes the keyword. They improve readability when the sentence remains unambiguous:
*** Test Cases ***
Readable variants
[Template] Identifier "${candidate}" should be ${expected}
abc ACCEPT
ab-c REJECT
*** Keywords ***
Identifier "${candidate}" should be ${expected}
${actual}= Classify Identifier ${candidate}
Should Be Equal ${actual} ${expected}
Embedded arguments are still keyword arguments, not a separate BDD engine. Spaces and underscores are not normalized in embedded keyword names the same way as ordinary names, and ambiguous patterns can match the wrong text. Quote or otherwise delimit values when boundaries may contain spaces.
8. Keyword-driven, data-driven, and BDD-style are presentation choices
| Style | Best fit | Failure identity risk |
|---|---|---|
| Keyword-driven | One workflow with several meaningful steps | Duplication if copied for many variants |
| Data-driven | Same contract, varying inputs/expected outputs | Rows become opaque if names/context are weak |
| BDD-style wording | Readable requirement language around keywords | Can become ceremony if Given/When/Then hides technical ownership |
| FOR loop | One test intentionally iterates a collection as one behavior | Iterations are not separate test identities |
9. Data rows are visible test source, not a secret store
Variant tables normally appear in source control, logs, and result
artifacts. Use synthetic usernames, tokens such as
token-FAKE_DO_NOT_USE, and non-sensitive identifiers.
Real credentials belong in a secret-management boundary and are
injected without being copied into data rows. Chapter 23 goes deeper
into Secret variables and credential hygiene.
10. Why this matters in DevOps
Data-driven tests can increase coverage density dramatically, but CI
needs stable ownership and failure identity. A named row such as
Too short identifier tells an operator what failed; a
500-row anonymous matrix does not. The test source, execution
command, variant data, framework version, and result artifacts
together form the evidence needed for reruns and release decisions.
11. Knowledge check
If one multi-row template iteration fails, do later rows execute in Robot Framework 7.4.2?
Yes. Templated tests automatically continue through their top-level iterations. The overall test fails if any iteration fails.
Does each row inside one templated test become a separately selectable Robot test?
No. The test has one source/test identity; the rows are template iterations visible in the log. Use separate named tests with a suite-level Test Template when each variant needs separate test identity.
What does an embedded argument change?
It changes how a keyword call captures arguments from its name and can improve readability. It does not create a separate BDD engine or external state store.
Why should real secrets not appear in a template table?
The table is source data and its values may be visible in source control and result artifacts. Use a proper secret-injection boundary instead.
12. Summary and next step
A data-driven suite starts with one invariant contract and explicit variant data. Separate named tests maximize CI identity; multi-row templates maximize compactness but aggregate status. Embedded arguments improve readable keyword calls when matching is unambiguous. Lesson 2 turns these distinctions into a runnable synthetic identifier-validation workflow and compares templates with loops and explicit tests.
Further reading
- Robot Framework 7.4.2 User Guide — Test templates — basic templates, multiple iterations, embedded arguments, FOR, and IF/ELSE.
- Robot Framework 7.4.2 User Guide — Different test case styles — keyword-driven, data-driven, and BDD-style presentation.
- Robot Framework 7.4.2 User Guide — Embedded arguments — matching rules, ambiguity, and custom regular expressions.
- Robot Framework 7.4.2 User Guide — User-keyword argument conversion — typed user keyword arguments available from 7.3.
- Robot Framework 7.4.2 on PyPI — pinned stable package metadata and Python requirement.
- Robot Framework releases — re-check stable and pre-release status when updating the course.
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.