Chapter 04Lesson 05190–250 min

Checkpoint Lab — Test Cases, Tasks, Suites, Names, Documentation, and Metadata

Build a three-level disposable suite hierarchy with meaningful metadata and positive/negative cases, execute it from two deliberate roots, explain the resulting identity differences, and finish with an evidence-backed naming and suite-boundary convention.

Checkpoint labThree-level suiteTwo rootsEvidence packetNaming policy

Checkpoint objectives

  • Create a three-level suite hierarchy whose root, child directory, file suite, and test identities are predictable before execution.
  • Use safe documentation, metadata, tags, and __init__.robot configuration without hidden child-scope assumptions.
  • Execute the same physical file under two deliberate roots and explain the resulting full-name and metadata differences.
  • Produce machine-readable and human-readable evidence plus a naming/suite-boundary decision record.
  • Clean up only the guarded disposable project after independently verifying the checkpoint results.

Checkpoint baseline. Robot Framework 7.4.2, supported Python (examples assume 3.12.x), BuiltIn only, synthetic strings only. Do not add real accounts, production URLs, secrets, browser/API/database/SSH targets, Pabot, containers, or CI dependencies. The purpose is suite identity and governance evidence.

1. Scenario and target hierarchy

You own a synthetic checkout release gate. The project needs one root suite representing release quality, one component directory representing checkout, one file suite representing payment decisions, and two cases: one positive and one negative. The same file will then be executed from the release root and from the checkout directory so you can prove which identity/configuration changes.

rf-suite-checkpoint/
├── release_quality/
│   ├── __init__.robot
│   └── checkout/
│       ├── __init__.robot
│       └── payment.robot
├── evidence/
│   ├── root-run/
│   └── checkout-run/
└── decisions/
    ├── predictions.txt
    └── suite-convention.md

2. Preflight and path guard

Create the checkpoint in a new disposable directory. Before any write, record runtime provenance and the working path:

python --version
python -m robot --version
pwd    # Bash / POSIX
# PowerShell alternative: Get-Location

Confirm the path is the intended disposable checkpoint location. No cleanup command later in this lab should target anything outside rf-suite-checkpoint.

3. Create the root directory suite

Save as release_quality/__init__.robot:

*** Settings ***
Name             Release Quality
Documentation    Synthetic release evidence for the Chapter 04 checkpoint.
Metadata         Owner    quality-platform
Metadata         Evidence Class    synthetic
Metadata         Requirement Set    RF-CH04
Test Tags        chapter-04    synthetic

Prediction 1: when release_quality is the executed root, the root name will be Release Quality, its metadata will be present in the result, and descendant tests will receive the root test tags.

4. Create the checkout directory suite

Save as release_quality/checkout/__init__.robot:

*** Settings ***
Name             Checkout
Documentation    Synthetic checkout decision boundary.
Metadata         Component    checkout
Metadata         Owner    checkout-quality

This is the second suite level. It adds component context without defining child variables or keywords. Prediction 2: when checkout is executed directly, this initialization file still applies because it belongs to the root itself, but release_quality/__init__.robot is above the root and is ignored.

5. Create the payment file suite and positive/negative cases

Save as release_quality/checkout/payment.robot:

*** Settings ***
Documentation    Deterministic synthetic payment-decision checks.
Metadata         Requirement    RF-CH04-PAYMENT

*** Test Cases ***
Approved Synthetic Card Is Accepted
    [Documentation]    Positive case using a harmless local string.
    [Tags]    positive    smoke
    Should Be Equal    approved    approved

Declined Synthetic Card Is Not Accepted
    [Documentation]    Negative case: a declined state must differ from approved.
    [Tags]    negative
    Should Not Be Equal    declined    approved

The file is the third suite level. Both tests are deterministic and use only BuiltIn assertions, so any hierarchy difference is attributable to suite architecture rather than an external system.

6. Write the prediction sheet before execution

In decisions/predictions.txt, record at least these predictions:

RUN A: python -m robot --dryrun --outputdir evidence/root-run release_quality
Root suite: Release Quality
Child suite: Release Quality.Checkout
File suite: Release Quality.Checkout.Payment
Positive full name: Release Quality.Checkout.Payment.Approved Synthetic Card Is Accepted
Root metadata expected: yes
Root chapter-04/synthetic tags expected on tests: yes

RUN B: python -m robot --dryrun --outputdir evidence/checkout-run release_quality/checkout
Root suite: Checkout
File suite: Checkout.Payment
Positive full name: Checkout.Payment.Approved Synthetic Card Is Accepted
Release Quality metadata expected: no
Root chapter-04/synthetic tags expected from release_quality/__init__.robot: no

Do not edit this file after seeing the results without preserving the original prediction. The checkpoint is testing your model, not your ability to rewrite history.

7. Execute both deliberate roots

python -m robot --dryrun --outputdir evidence/root-run release_quality
python -m robot --dryrun --outputdir evidence/checkout-run release_quality/checkout

Both runs should PASS in dry-run. If either does not, preserve its evidence directory unchanged, diagnose the source/model/import issue, and write repaired evidence to a new directory. Do not overwrite the first failure.

8. Inspect full names, metadata, tags, and statuses

from robot.api import ExecutionResult

for label in ("root-run", "checkout-run"):
    result = ExecutionResult(f"evidence/{label}/output.xml")
    print(f"\n=== {label} ===")

    def walk(suite, depth=0):
        print("  " * depth + f"SUITE: {suite.full_name}")
        if suite.metadata:
            print("  " * (depth + 1) + f"METADATA: {dict(suite.metadata)}")
        for test in suite.tests:
            print("  " * (depth + 1) + f"TEST: {test.full_name}")
            print("  " * (depth + 2) + f"TAGS: {list(test.tags)} STATUS: {test.status}")
        for child in suite.suites:
            walk(child, depth + 1)

    walk(result.suite)

Verify the predictions independently in the HTML log/report too. The root-run should show the three-level suite chain Release Quality → Checkout → Payment. The checkout-run should show Checkout → Payment. The physical payment file did not move; the execution root changed the model.

9. Explain the before/after hierarchy differences

Observation Root run Checkout run Reason
Top-level suite Release Quality Checkout Different executed root.
Payment suite full name Release Quality.Checkout.Payment Checkout.Payment Full name prefixes participating parents.
Root owner metadata quality-platform visible not present Root initialization is outside checkout-run tree.
Checkout metadata checkout-quality visible checkout-quality visible Checkout initialization participates in both runs.
Root recursive tags chapter-04, synthetic expected not inherited from Release Quality Root Test Tags only apply when root init participates.
Test bodies same same Source file is unchanged; only execution hierarchy differs.

10. Produce the suite naming and boundary convention

Create decisions/suite-convention.md with a concise team-ready policy. It should include at least these rules:

  1. One durable reason per suite level. Root = release evidence domain; child directory = component ownership; file suite = focused behavior/workflow.
  2. Names are stable interfaces. Use concise domain names; review Name/path changes as selector/report migrations.
  3. Documentation explains intent. Do not encode paragraphs into names.
  4. Metadata is non-sensitive context. Owner/component/requirement/evidence class are allowed; secrets and PII are forbidden.
  5. Tags are selection classes. Smoke/negative/risk classifications must have documented meanings.
  6. Initialization is suite configuration. Do not rely on it for hidden variable/keyword inheritance.
  7. CI uses a canonical root. Narrow runs should normally select under that root when parent lifecycle/identity matters.
  8. Tests and tasks have separate roots and operational meaning.

11. Assemble the evidence packet

The checkpoint packet should contain:

  • exact Python and Robot Framework version output;
  • the source directory tree;
  • all three Robot source files;
  • the original prediction sheet;
  • the two exact execution commands;
  • evidence/root-run/output.xml, log.html, and report.html;
  • evidence/checkout-run/output.xml, log.html, and report.html;
  • the result-inspection script/output;
  • the completed hierarchy comparison;
  • suite-convention.md.

Everything is synthetic, but use the same privacy mindset you would in production: inspect artifacts before publishing them to a CI system or long-term archive.

12. Independent verification checklist

  • Exactly two tests exist and both PASS in each dry-run.
  • The positive and negative test bodies are identical across both runs.
  • Run A full names begin with Release Quality.Checkout.Payment.
  • Run B full names begin with Checkout.Payment.
  • Release Quality metadata appears only when that root participates.
  • Checkout metadata appears in both runs.
  • Root recursive tags are not assumed when the root initialization is outside the executed tree.
  • No secret, real URL, personal path, or external-system state appears in the packet.
  • The convention explicitly distinguishes names, documentation, metadata, tags, paths, tests/tasks, and initialization scope.

13. Cleanup and rollback

Keep the checkpoint if you want to compare it with Chapter 05. If deleting it, first move to its parent directory and print/inspect the exact target. Remove only the known rf-suite-checkpoint directory. Do not paste a generic recursive delete command against an unknown current directory.

There is no external rollback because the lab never touched a browser, API, database, SSH server, CI environment, container, or production system. The only mutable state is the guarded local checkpoint directory.

14. Knowledge check

Why does the same payment test have two different full names in the checkpoint?

Why does Checkout metadata remain visible in both runs?

If the release owner metadata disappeared in Run B, should you copy it into payment.robot?

What makes the naming convention operational rather than cosmetic?

What should Chapter 05 add to this operating model?

15. Production operating model and bridge to Chapter 05

Chapter 04 adds stable executable identity to the production Robot Framework model: a canonical execution root, meaningful directory/file suite boundaries, predictable full names, safe documentation/metadata, governed tags, explicit initialization scope, tests/tasks separated by intent, and evidence that records the exact hierarchy that ran.

Chapter 05 moves from where executable cases live to how behavior is abstracted. You will design user keywords with explicit arguments and return values so reuse happens through visible contracts rather than copied procedural steps or hidden suite state.

Next lesson

Keywords, Arguments, Return Values, and Reusable Abstractions: Core Concepts and Mental Model

Continue with Keywords, Arguments, Return Values, and Reusable Abstractions: Core Concepts and Mental Model. 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.