Chapter 27Lesson 02210–270 min

Style Guides, Robocop, Documentation, Naming, and Maintainability: Guided Hands-On Workflow

Turn style policy into an observable local workflow: preserve a baseline, lint, preview formatting, apply only reviewed mechanical changes, refactor semantics manually, generate Libdoc, and verify CI-style exit codes.

Robocop checkRobocop formatTOMLLibdocDisposable lab

Learning objectives

  • Create a disposable multi-file Robot project whose initial source is valid but intentionally inconsistent.
  • Use Robocop lint and non-destructive formatter preview before source mutation.
  • Configure a staged policy in pyproject.toml with a Robot target version and controlled exclusions.
  • Distinguish automatic formatting from manual semantic naming/documentation refactoring.
  • Produce style, Libdoc, dry-run, and exit-code evidence suitable for a CI gate.

Current compatibility baseline — verified 2026-09-01. Robot Framework 7.4.2 is the stable course baseline and requires Python 3.8+. This chapter pins Robocop 9.0.0, released 2026-08-26, which requires Python 3.10+ and Robot Framework 5+. The combined mandatory lab therefore uses Python 3.10+. The Robot Framework community Style Guide currently identifies itself as 0.10b. Modern Robocop has two modes: robocop check for lint/static analysis and robocop format for formatting. Standalone Robotidy is not the recommended new workflow because its formatter functionality was merged into Robocop 6+. Formatting is source normalization, not proof of good architecture.

1. Scenario and ownership boundary

You are standardizing a small synthetic order-automation project. It has no network access and no production target. The source is intentionally inconsistent but parser-valid. The goal is to prove each transition independently: parser-valid → lint findings → formatter preview → normalized source → manual semantic cleanup → documented reusable API → clean CI-style gate.

Path Purpose May be changed by
suites/orders.robot Executable synthetic test Formatter + manual refactor
resources/order_keywords.resource Reusable domain keywords Formatter + manual refactor
generated/example.resource Simulated generated/vendor source Nobody in the style workflow
pyproject.toml Pinned team Robocop policy Human review only
evidence/ Diffs, versions, outputs, Libdoc Commands in this lab

2. Preflight: prove versions and start from a clean disposable directory

python --version
python -m robot --version
robocop --version
python -m robot.libdoc --help

# Create a local disposable lab folder. Do not point these commands at a production repo first.
mkdir -p rf27-style-lab/suites rf27-style-lab/resources rf27-style-lab/generated rf27-style-lab/evidence
cd rf27-style-lab
python --version
python -m robot --version
robocop --version
python -m robot.libdoc --help
New-Item -ItemType Directory -Force rf27-style-lab\suites, rf27-style-lab\resources, rf27-style-lab\generated, rf27-style-lab\evidence | Out-Null
Set-Location rf27-style-lab

The only mutable state is the lab directory. If you adapt the workflow to an existing repository, create a branch or clean commit first so the formatter diff has a trustworthy baseline.

3. Create parser-valid but intentionally inconsistent source

Robot accepts two or more spaces between cells, so the following is intentionally valid even though it does not follow the four-space convention used by the current formatter defaults.

*** Settings ***
Documentation  Synthetic order style lab.
Resource  ../resources/order_keywords.resource

*** Test Cases ***
process_order_smoke
  ${summary}=  build_order_summary  ORD-001  widget  2
  Should Be Equal  ${summary}  ORD-001|widget|2

Save it as suites/orders.robot. Then save this resource:

*** Keywords ***
build_order_summary
  [Arguments]  ${order_id}  ${item_name}  ${quantity}
  ${summary}=  Catenate  SEPARATOR=|  ${order_id}  ${item_name}  ${quantity}
  RETURN  ${summary}

Save as resources/order_keywords.resource. Finally create a simulated generated file that must remain untouched:

*** Keywords ***
generated_machine_name
  Log  Do not reformat generated sources in this lab

Save as generated/example.resource.

4. Baseline before formatting: parser and linter are separate observations

python -m robot --dryrun --outputdir evidence/dryrun suites
robocop check suites resources | tee evidence/robocop-before.txt
python -c "from pathlib import Path; import hashlib; p=Path('generated/example.resource'); print(hashlib.sha256(p.read_bytes()).hexdigest())" > evidence/generated-before.sha256

The dry run proves Robot can parse/import/resolve the suite without executing external systems. Robocop may report naming, documentation, spacing, or other enabled findings depending on the current default rule set. Preserve the exact output instead of teaching a brittle “you must see exactly N findings” assertion. The generated-file hash becomes independent proof that later style commands did not touch excluded content.

5. Preview formatting before source mutation

robocop format --no-overwrite --diff suites resources > evidence/format-preview.txt
robocop format --check suites resources
echo $? > evidence/format-check-before.exit

--no-overwrite --diff is the review mode: it calculates the formatter result and displays a unified diff without changing source. --check also avoids overwriting by default and returns exit code 1 if any file would be formatted. That makes it suitable for CI.

Do not skip the preview on a tool upgrade. Formatter behavior can evolve. A pinned version plus a reviewed diff protects generated files and semantics from accidental mass rewrites.

6. Add a staged project policy in pyproject.toml

[tool.robocop]
target-version = 7
exclude = ["generated", "evidence"]
force-exclude = true

[tool.robocop.lint]
extend-select = [
    "missing-doc-keyword",
    "missing-doc-test-case",
]
configure = [
    "line-too-long.line_length=100",
]

[tool.robocop.format]
space-count = 4
line-length = 100
line-ending = "unix"

target-version = 7 tells Robocop to evaluate rules and formatters against Robot Framework major version 7 even if Robocop runs in an environment with newer Robot later. extend-select keeps the normal default rules and adds explicit documentation checks. Excluding generated/evidence directories prevents mechanical rewrites of artifacts. force-exclude = true matters when automation passes explicit paths because directly specified files otherwise take precedence over exclusion patterns.

This is deliberately a staged baseline. Selecting every disabled rule at once can convert a style migration into a massive unrelated refactor.

7. Apply mechanical formatting, then inspect the diff

robocop format suites resources
git diff --no-index /dev/null suites/orders.robot 2>/dev/null || true
robocop format --check suites resources
robocop check suites resources | tee evidence/robocop-after-format.txt

If the lab is not in Git, simply inspect the files or copy them before/after. The formatter should normalize layout, but explicit documentation rules may still fail. That is correct: source normalization and documentation design are different concerns.

8. Perform the semantic refactor by hand

Replace the test with a readable outcome-oriented name and improve the reusable keyword contract:

*** Settings ***
Documentation    Synthetic order style lab.
Resource         ../resources/order_keywords.resource

*** Test Cases ***
Build Synthetic Order Summary
    [Documentation]    Verifies the reusable order-summary contract with synthetic data only.
    ${summary}=    Build Order Summary    ORD-001    widget    2
    Should Be Equal    ${summary}    ORD-001|widget|2
*** Keywords ***
Build Order Summary
    [Documentation]    Builds a stable order summary without external side effects.
    [Arguments]    ${order_id}    ${item_name}    ${quantity}
    ${summary}=    Catenate    SEPARATOR=|    ${order_id}    ${item_name}    ${quantity}
    RETURN    ${summary}

The formatter could change build_order_summary capitalization if a formatter is configured to do so, but it cannot know that Build Order Summary is the intended domain phrase or that “synthetic/no external side effects” is the contract worth documenting. Those are human choices.

9. Generate interface documentation and execute the controlled slice

python -m robot.libdoc resources/order_keywords.resource evidence/order_keywords.html
robocop check suites resources | tee evidence/robocop-final.txt
robocop format --check suites resources
echo $? > evidence/format-check-final.exit
python -m robot --outputdir evidence/run suites

Libdoc reads the reusable resource and writes HTML documentation. The final Robot run provides functional evidence; Robocop and Libdoc do not replace it. Keep the style exit codes and Robot result artifacts as different evidence categories.

10. A minimal CI-ready style command sequence

python --version
python -m robot --version
robocop --version
robocop check suites resources
robocop format --check suites resources
python -m robot --dryrun --outputdir evidence/ci-dryrun suites

Run style gates early because they are local, deterministic, and cheaper than browser/API/infrastructure tests. Do not hide a failing linter behind || true or an “exit zero” option merely to produce a green pipeline.

Challenge: choose the correct layer

For each case, choose formatter, linter/config, manual refactor, or runtime test: (A) cells use inconsistent spacing; (B) a resource lacks keyword documentation; (C) one keyword mixes payment and notification; (D) a renamed keyword still calls the correct API. Explain what evidence proves your choice.

Expected reasoning. A → formatter preview/apply. B → linter detects policy; human writes useful docs. C → manual architecture refactor; a formatter cannot solve it. D → runtime/dry-run plus functional evidence; style tooling cannot prove integration behavior.

11. Evidence matrix

Evidence What it proves What it does not prove
robocop-before.txt Initial static findings under pinned config/version. Runtime correctness.
format-preview.txt Exact proposed source normalization. That changes are semantically desirable.
Formatter check exit code Whether committed source matches formatter policy. Architecture quality.
Libdoc HTML Published reusable keyword signatures/docs. Documentation accuracy.
Robot dry-run/run artifacts Parser/import/runtime contract for controlled suite. Style compliance.
Generated-file hashes Excluded artifact remained byte-identical. Other files were safe.

Knowledge check

Why run a Robot dry-run before the first format operation?

Why use both robocop format --no-overwrite --diff and robocop format --check?

Why is force-exclude useful in this lab?

A formatter produces no diff, but one keyword performs five unrelated irreversible actions. What next?

Summary and bridge

You now have a repeatable local style pipeline with preserved baselines, non-destructive preview, staged policy, manual semantic cleanup, Libdoc, and CI-style exit codes. Lesson 3 turns these mechanics into design decisions for migrations, suppressions, auto-fix, naming, generated files, hooks, and upgrade policy.

Next lesson

Style Guides, Robocop, Documentation, Naming, and Maintainability: Configuration, Design Patterns, and Trade-Offs

Continue with Style Guides, Robocop, Documentation, Naming, and Maintainability: 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.

Current primary references

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.