Robocop for Robot Framework

repository·main·Indexed 42 days ago

https://github.com/marketsquare/robotframework-robocop

A static code analysis tool (linter) and code formatter for Robot Framework. Robocop uses the official Robot Framework parsing API to identify linting issues, enforce code quality standards, and apply automatic fixes. It supports configuration via TOML files (pyproject.toml, robocop.toml, robot.toml), custom Python rules, and provides an MCP server for AI assistants.

Tokens
119.6K
Snippets
563
Records
700
Agent score
53%

What's inside Robocop

  1. Overview of Robocop rule categories

    main

    Robocop provides over 190 rules for linting Robot Framework code, organized into several functional categories. When searching for specific linting constraints, you can look for rules prefixed with these category codes:

    • ARG: Arguments
    • COM: Comments
    • DEPR: Deprecated code
    • DOC: Documentation
    • DUP: Duplications
    • ERR: Errors
    • GRP: Groups
    • IMP: Imports
    • KW: Keywords
    • LEN: Lengths
    • MISC: Miscellaneous
    • NAME: Naming
    • ORD: Order
    • SPC: Spacing
    • TAG: Tags
    • VAR: Variables
    • ANN: Annotations
  2. Configure variable scope with VAR

    main

    The VAR syntax supports setting the variable scope using the scope= parameter. This replaces specific scope-setting keywords. By default, VAR uses the local scope, but you can explicitly set it using scope=LOCAL (or via the explicit_local parameter in the formatter configuration).

    *** Keywords ***
    Custom Keyword
        # Local scope (default)
        VAR    ${var}    value
        VAR    ${var}    value    scope=LOCAL
    
        # Task scope
        VAR    ${task_variable}    value    scope=TASK
    
        # Test scope
        VAR    ${test_variable}    ${test_variable}    scope=TEST
    
        # Suite scope
        VAR    ${suite_variable}    value    scope=SUITE
    
        # Global scope
        VAR    ${global_variable}    value    scope=GLOBAL
  3. Understand how OrderSettings reorders Robot Framework settings

    main

    The OrderSettings formatter automatically reorders Robot Framework settings (like [Arguments], [Setup], [Tags], etc.) within Test Cases and Keywords to ensure a consistent structure.

    Test Case Ordering

    • Before the body: [Documentation], [Metadata], [Tags], [Template], [Timeout], and [Setup] are moved to the top of the test case.
    • After the body: [Teardown] is moved to the end of the test case.
    • Note: [Metadata] requires Robot Framework 7.5+ and can appear multiple times; all occurrences are preserved in their original relative order.

    Keyword Ordering

    • Before the body: [Documentation], [Tags], [Timeout], [Arguments], and [Setup] are moved to the top of the keyword.
    • After the body: [Teardown] and [Return] are moved to the end of the keyword.
    *** Test Cases ***
    Test
        [Documentation]    Test documentation.
        [Tags]    tags
        [Template]    Template
        [Timeout]    60 min
        [Setup]    Setup
        Test Step
        [Teardown]    Teardown
    
    
    *** Keywords ***
    Keyword
        [Documentation]    this is
        ...    doc
        [Tags]    sanity
        [Arguments]    ${arg}
        Pass
        [Teardown]    Keyword
        [Return]    ${value}
  4. How RenameVariables works

    main

    The RenameVariables formatter renames and normalizes variable names across Settings, Variables, Test Cases, Keywords, and Tasks sections, including variables in arguments.

    Default Conventions:

    • Case: Local variables are lowercase; non-local (global) variables are uppercase.
    • Whitespace: Leading/trailing whitespace is stripped; multiple consecutive whitespaces are collapsed to one; spaces are replaced by _ (or a configured separator).
    • Naming: camelCase is converted to snake_case.

    Limitations:

    • Variables passed by variable (e.g., $var) are currently ignored.
    • Renaming camelCase to snake_case may break keyword calls using keyword arguments (kwargs) if the call site is not updated.

    To locally disable this formatter for specific code blocks, use # robocop format: off.

    *** Settings ***
    Suite Setup    ${keyword}  # Becomes ${KEYWORD}
    
    *** Variables ***
    ${global}    String    # Becomes ${GLOBAL}
    
    *** Test Cases ***
    Test
        ${local}    Set Variable    val  # Stays ${local}
        Log    ${global}               # Becomes ${GLOBAL}
    
    *** Keywords ***
    Keyword
        [Arguments]    ${ARG}          # Becomes ${arg}
        Log    ${arg}
  5. Use multiple configuration files in Robocop

    main

    Robocop supports hierarchical configuration. You can place different configuration files (e.g., pyproject.toml) in different subdirectories to apply specific rules or exclusions to those specific directories.

    Files in a subdirectory will use the configuration closest to them. For example, a pyproject.toml in a subdir/ will apply to files within that subdirectory, allowing you to override or extend the project-level configuration.

    Note: Settings that affect the entire run (such as --persistent, --exit-zero, or report generation) are only loaded from the configuration file closest to the current working directory or from the CLI, not from nested files.

    project/
        file1.robot        # uses project/pyproject.toml
        pyproject.toml     # config1
        subdir/
            file1.robot    # uses project/subdir/pyproject.toml
            file2.robot    # uses project/subdir/pyproject.toml
            pyproject.toml # config2
  6. How project-level rules work

    main

    Project-level rules (marked with the [project] tag) analyze the entire project context rather than individual files. This allows Robocop to detect issues like unused keywords or circular imports.

    Important Behaviors:

    • Disabled by Default: Project rules are disabled by default and must be explicitly selected.
    • Context Building: When at least one project rule is enabled, Robocop parses every source file in the project to build a global index of keywords, variables, and imports.
    • Execution Risk: To analyze libraries, Robocop executes the code of imported libraries and Python variable files. Use --no-analyze-libraries to skip this or --ignored-library to skip specific ones.
    • Performance: Project analysis is slower than file-level linting. Use --no-project to skip project context building in fast environments like pre-commit hooks.
    # Run only project-level rules
    robocop check --select PROJECT
    
    # Run default rules AND all project-level rules
    robocop check --extend-select PROJECT
    
    # Run every rule (default + project) explicitly
    robocop check --select ALL --extend-select PROJECT
    
    # Skip project analysis for speed
    robocop check --no-project
  7. Configure file discovery for Robocop

    main

    By default, Robocop searches for .robot and .resource files in the current directory and subdirectories.

    Customizing search paths

    You can pass a list of paths to limit where Robocop looks:

    robocop check tests/ bdd/ example.robot

    Filtering and Exclusions

    • --exclude: Configure additional paths to ignore.
    • --default-exclude: Defaults to .direnv, .eggs, .git, .svn, .hg, .nox, .tox, .venv, venv, dist.
    • --include: Configure additional paths to include (e.g., *.txt).
    • --default-include: Defaults to *.robot, *.resource.
    • .gitignore: Robocop automatically respects .gitignore files. Use --skip-gitignore to disable this.
    • CLI Path Priority: Paths passed directly via CLI are always included even if they don't match --default-include. To apply exclude filters to CLI paths, use --force-exclude.
  8. Load external rules from Python modules

    main

    Robocop's improved import mechanism allows it to parse and load external Robocop rules defined inside modules that are imported within your Python files.

    Previously, only the CustomChecker would be loaded. Now, if your Python file contains imports like import custom_rules.naming, Robocop will also discover and load any external rules defined within those modules.

    # Example of how external rules are now automatically discovered
    import custom_rules.naming
    import custom_rules.errors
    from custom_rules.lengths import rules, CustomChecker
  9. How SmartSortKeywords works

    main

    The SmartSortKeywords formatter sorts keywords within the *** Keywords *** section of Robot Framework files.

    Default Behavior:

    • Case Insensitivity: Sorting is case-insensitive by default.
    • Leading Underscores: Keywords starting with an underscore (_) are moved to the bottom of the list.
    • Underscore Treatment: Underscores within a keyword name (that are not leading) are treated as spaces for sorting purposes.
    • Whitespace Preservation: Empty lines (or the lack thereof) between keywords are preserved during the sorting process.

    You can customize this behavior using the following parameters:

    • case_insensitive
    • ignore_leading_underscore
    • ignore_other_underscore
    *** Keywords ***
    _my secrete keyword
        Kw2
    
    My Keyword
        Kw1
    
    
    my_another_cool_keyword
    my another keyword
        Kw3

    Becomes (Sorted):

    *** Keywords ***
    my_another_cool_keyword
    
    my another keyword
        Kw3
    
    
    My Keyword
        Kw1
    _my secrete keyword
        Kw2
  10. Override default configuration files with --argumentfile

    main

    When using the --argumentfile (or -A) CLI option, Robocop will now only use the specified argument file and will not read the default configuration files (such as .robocop or pyproject.toml).

    If you do not provide the --argumentfile option, Robocop will continue to use the default configuration file found on disk as a base.

    robocop --argumentfile myconfig.txt
  11. How NormalizeNewLines handles language markers

    main

    Files starting with a language marker (e.g., language: pl) are treated specially.

    If a section contains only the language marker and no more empty lines than the configured section_lines, it will not be formatted.

    Formatting will occur if:

    1. The section contains more empty lines than section_lines.
    2. The section contains statements/comments other than just the language marker.