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.
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.tomlwith 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?
It proves the baseline source is parser/import-valid. If a later problem appears, you can distinguish pre-existing semantic defects from formatter or manual changes.
Why use both robocop format --no-overwrite --diff and robocop format --check?
The diff is human-review evidence; check is a machine-friendly policy gate with a meaningful exit code and no overwrite by default.
Why is force-exclude useful in this lab?
Because explicit command-line file paths can otherwise be processed even when they match exclusion patterns. force-exclude makes exclusions apply consistently.
A formatter produces no diff, but one keyword performs five unrelated irreversible actions. What next?
Manual semantic refactoring and runtime safety design. Formatter convergence only proves the mechanical source representation is normalized.
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.
Current primary references
- Robocop getting started — Current check/format commands and requirements.
- Robocop formatter — Preview, overwrite and check behavior.
- Robocop configuration reference — Target version, exclusions, per-file ignores and fix controls.
- Robot Framework Style Guide — Community naming/spacing/style guidance.
- Robot Framework Libdoc — Reusable library/resource documentation generation.
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.