Command-Line Selection, Tag Expressions, Reruns, and Execution Profiles: Guided Hands-On Workflow
Build a disposable local selection lab, prove smoke/regression/environment slices, capture exact selection evidence, rerun only a controlled failed test, and merge without destroying the original failure.
Learning objectives
- Create a five-test local suite whose selection counts are known before execution.
- Run by test, suite, include/exclude, skip, and argument-file contracts.
- Use a fake environment variable input without confusing it with a tag.
- Create an intentional first failure, rerun only that test, and merge without overwriting original evidence.
- Explain each filesystem/result mutation and its owner.
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. Core examples use python -m robot and
python -m robot.rebot so the interpreter is explicit.
RobotCode is not Robot Framework core; where shown as an optional
profile layer, the pinned example is RobotCode
2.7.0, which requires Python 3.10+ and Robot
Framework 5.0+. Mandatory labs do not require RobotCode, Pabot,
browsers, containers, CI accounts, or paid services.
1. Scenario and safety boundary
The lab is deliberately local: five synthetic tests, no network, no
subprocess, no real credentials, and all outputs under a dedicated
results/ directory. The only state changes are Robot
result artifacts. This keeps the lesson focused on selection and
rerun semantics.
Safety rule: never reuse these commands against production targets merely by changing a variable. This suite contains no external integration by design. Chapter 16 introduces browser state explicitly.
2. Preflight and project tree
python --version
python -m robot --version
# Expect Robot Framework 7.4.2 for the pinned walkthrough.
mkdir rf-cli-lab
cd rf-cli-lab
# Create these paths manually or with your editor:
# tests/service.robot
# tests/environment.robot
# config/smoke.args
# results/ (created by Robot)
rf-cli-lab/
├── config/
│ └── smoke.args
├── tests/
│ ├── service.robot
│ └── environment.robot
└── results/ # generated evidence only
3. Create deterministic source with known tag membership
*** Settings ***
Documentation Synthetic service checks for CLI selection.
*** Variables ***
${TARGET_ENV} local
${FORCE_FAILURE} no
*** Test Cases ***
Health Is Smoke
[Tags] smoke regression
Should Be Equal ${TARGET_ENV} local
Invoice Is Regression
[Tags] regression
Should Be Equal ${TARGET_ENV} local
Archive Is Slow Regression
[Tags] regression slow
Should Be Equal ${TARGET_ENV} local
Controlled Failure
[Tags] regression rerun-demo
IF $FORCE_FAILURE == "yes"
Fail Synthetic rerun contract failure
END
Should Be Equal ${FORCE_FAILURE} no
$FORCE_FAILURE is used as an expression variable so the
string value is compared as a Python value rather than inserted into
expression text. No external state changes: only Robot status/result
state changes when the synthetic failure is enabled.
*** Settings ***
Documentation Environment variant with explicit configuration.
*** Variables ***
${TARGET_ENV} local
${EXPECTED_ENV} local
*** Test Cases ***
Environment Contract
[Tags] smoke env
Should Be Equal ${TARGET_ENV} ${EXPECTED_ENV}
4. Predict the selection matrix before running
| Slice | Selector | Predicted tests | Count |
|---|---|---|---|
| Smoke | --include smoke |
Health Is Smoke; Environment Contract | 2 |
| Regression | --include regression |
Health; Invoice; Archive; Controlled Failure | 4 |
| Regression, not slow | --include regression --exclude slow |
Health; Invoice; Controlled Failure | 3 |
| Environment | --include env |
Environment Contract | 1 |
| Service suite | --suite Tests.Service |
Four tests from service.robot | 4 |
This prediction is evidence in its own right. If the observed counts differ, investigate selection first instead of assuming the tests are wrong.
5. Baseline run and name selection
# From rf-cli-lab/ only.
python -m robot --outputdir results/all tests
# Smallest controlled slice by test name.
python -m robot --test "Health Is Smoke" --outputdir results/one tests
# Preserve the root suite while selecting its Service child.
python -m robot --suite "Tests.Service" --outputdir results/service tests
The first run should report five PASS tests. The test-only run
should report one PASS. The suite run should report the four service
tests. In each directory, inspect output.xml,
log.html, and report.html. These files are
newly created filesystem evidence; the source remains unchanged.
6. Run smoke/regression/skip slices and compare evidence
python -m robot --include smoke --outputdir results/smoke-manual tests
python -m robot --include regression --exclude slow --outputdir results/regression-fast tests
python -m robot --include regression --skip slow --outputdir results/regression-with-skip tests
| Run | Expected PASS | Expected SKIP | Expected omitted |
|---|---|---|---|
| smoke-manual | 2 | 0 | 3 non-smoke tests |
| regression-fast | 3 | 0 | Archive Is Slow Regression |
| regression-with-skip | 3 | 1 | Environment Contract (not regression) |
The third command proves the semantic difference:
Archive Is Slow Regression is visible as SKIP. In the
second it is excluded and does not represent a selected skipped
test.
7. Turn the smoke contract into a core argument file
# config/smoke.args
--include smoke
--exclude slow
--variable TARGET_ENV:local
--variable EXPECTED_ENV:local
--outputdir results/smoke-args
tests
python -m robot --argumentfile config/smoke.args
Expected count: 2 PASS. The file is Robot Framework core configuration. It sets no secret and touches no external system. Keep the exact file in version control if it defines a team execution contract.
cwd experiment: from the parent directory,
running
python -m robot --argumentfile
rf-cli-lab/config/smoke.args
will not make the embedded tests data-source path
relative to config/. The safest course contract is
“change to the project root first,” or normalize
absolute/project-root paths in a launcher. Do not repair this with
random PYTHONPATH changes.
8. Environment variant: configuration is a variable, selection is a tag
python -m robot --include env \
--variable TARGET_ENV:qa \
--variable EXPECTED_ENV:qa \
--outputdir results/env-qa tests
Exactly one test should run and pass. The env tag
selects the test; TARGET_ENV and
EXPECTED_ENV configure its synthetic value. This
separation scales cleanly into CI because changing environment does
not require changing test ownership tags.
9. Create and preserve an intentional first failure
python -m robot \
--variable FORCE_FAILURE:yes \
--outputdir results/initial \
--output original.xml \
tests
The process should return non-zero because
Controlled Failure fails. This is expected for the
lab. Do not append --nostatusrc, do not delete
results/initial/original.xml, and do not put this
command in an && chain that prevents you from
inspecting evidence after the expected failure.
Evidence to record: five tests selected, one failure, the exact
message Synthetic rerun contract failure, and the
original output path.
10. Rerun only failed tests with changed synthetic input
python -m robot \
--rerunfailed results/initial/original.xml \
--variable FORCE_FAILURE:no \
--outputdir results/rerun \
--output rerun.xml \
tests
Only Controlled Failure should run. It should pass.
The rerun output is a new artifact; it does not mutate the original.
If Robot says the prior output has no failed tests, stop and confirm
you pointed at the expected original rather than using
--runemptysuite to suppress the diagnostic.
11. Merge as a derived result, then verify provenance
python -m robot.rebot --merge \
--outputdir results/final \
--output merged.xml \
--log merged-log.html \
--report merged-report.html \
results/initial/original.xml \
results/rerun/rerun.xml
The merged result should show five tests and no final failures because the matching failed test was replaced by its rerun result. Your evidence packet must still contain both inputs. A release process may decide that “pass after rerun” needs separate approval; merging is a result operation, not a policy waiver.
12. Inspect output evidence without guessing
# Cross-platform Python inspection; read-only.
python - <<'PY'
from pathlib import Path
import xml.etree.ElementTree as ET
for p in [
Path("results/initial/original.xml"),
Path("results/rerun/rerun.xml"),
Path("results/final/merged.xml"),
]:
root = ET.parse(p).getroot()
tests = root.findall(".//test")
statuses = [t.find("status").get("status") for t in tests if t.find("status") is not None]
print(p, len(tests), statuses)
PY
This parser reads files only. It does not prove every semantic detail of the Robot result model, but it independently checks counts/statuses and the fact that all three evidence files exist.
13. Challenge: choose the right layer
You need a pull-request lane that runs all smoke tests except slow
ones against synthetic environment qa. Which
information belongs in tags and which belongs in variables? Then
decide whether a one-off local command or committed argument file is
the better contract. Explain the decision before running anything.
Verification and cleanup
- Baseline: 5 PASS.
- Smoke: 2 PASS.
- Regression excluding slow: 3 PASS.
- Regression skipping slow: 3 PASS + 1 SKIP.
- Environment slice: 1 PASS.
- Initial controlled run: 4 PASS + 1 FAIL.
- Rerun: only Controlled Failure, PASS.
- Merged: 5 tests, final PASS, with original and rerun inputs retained.
# Cleanup only the disposable lab you created.
cd ..
# PowerShell: Remove-Item -Recurse -Force .\rf-cli-lab
# Bash: rm -rf ./rf-cli-lab
Knowledge check
Why does --rerunfailed still need the current test
source path?
The prior output supplies failed-test identity for selection; Robot still parses the current source and executes matching current tests. The prior output is not executable test source.
The regression-with-skip run reports three PASS and one SKIP. Why is that not equivalent to excluding slow?
Because the slow regression remains selected evidence and receives SKIP status; exclusion removes it from ordinary selected-result evidence.
What is the first thing to inspect when smoke unexpectedly runs three tests instead of two?
Inspect the exact command/argument-file contents and the tags on the selected tests before changing assertions or test logic.
Why is changing FORCE_FAILURE from yes to no acceptable here?
It is a synthetic, explicitly documented input used to demonstrate rerun mechanics. A real flaky production failure should not be “fixed” by changing the system-under-test contract merely to obtain a pass.
Summary and bridge
You now have a reproducible selection/rerun lab with measurable evidence. Lesson 3 generalizes it into design decisions and precedence rules so teams can choose the simplest configuration surface that stays diagnosable.
References and version anchors
- Robot Framework 7.4.2 User Guide — CLI option syntax, name/tag selection, argument files, reruns, skip/exclude semantics, and result post-processing.
- Robot Framework 7.4.2 on PyPI — stable release and Python compatibility anchor.
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.