lyyyuna 的小花园

动静中之动, by

RSS

Robot Framework 新版教程 - 测试数据语法

发表于 2025-07

本文介绍了 Robot Framework 的测试数据语法,后续章节将详细讲解如何实际创建测试用例、测试套件等内容。虽然本节主要使用"测试"这一术语,但这些规则同样适用于创建任务。

文件和目录

构建测试用例的层次结构安排如下:

除此之外,还包括:

测试用例文件、测试套件初始化文件和资源文件均采用 Robot Framework 测试数据语法编写。而测试库和变量文件则使用"真正的"编程语言(通常为 Python)创建。

测试数据 section

Robot Framework 测试数据通过以下不同 section(通常也称为表格)进行定义:

不同 section 通过其 header 行进行识别。推荐的 header 格式是 ** Settings **,但 header 不区分大小写,前后空格可选,且开头的星号数量可以变化(只要至少有一个星号)。例如,*settings 也会被识别为 section header。

Robot Framework 也支持单数形式的 header(如 *** Setting ***),但从 Robot Framework 6.0 开始该支持已被弃用。自 Robot Framework 7.0 起会显示弃用警告,最终将完全不再支持单数形式的 header。

header 行除了实际的 section header 外,还可以包含其他内容。额外内容必须使用数据格式相关的分隔符(通常是两个或更多空格)与 section header 隔开。解析时会忽略这些额外内容,但可用于文档说明。这在采用数据驱动风格创建测试用例时特别有用。

第一个 section 之前的所有数据都会被忽略。

支持的文件格式

Robot Framework 最常见的数据创建方式是采用空格分隔格式,其中数据单元(如关键字及其参数)之间用两个或更多空格分隔。另一种方式是使用管道分隔格式,其分隔符为带空格的管道符( | )。

测试套件文件通常使用 .robot 扩展名,但实际可解析的文件类型可配置。资源文件也可使用 .robot 扩展名,但推荐使用专用的 .resource 扩展名,未来可能强制要求使用该扩展名。包含非 ASCII 字符的文件必须使用 UTF-8 编码保存。

Robot Framework 也支持 reStructuredText 文件,其中标准的 Robot Framework 数据被嵌入到代码块中。默认情况下,只有扩展名为 .robot.rst 的文件会被解析。若希望使用 .rst.rest 扩展名,需单独配置。

Robot Framework 数据还可采用 JSON 格式创建,该格式主要面向工具开发者而非普通用户。默认情况下,只有使用自定义 .rbt 扩展名的 JSON 文件会被解析。

早期 Robot Framework 版本还支持 HTML 和 TSV 格式的数据。若数据与空格分隔格式兼容,TSV 格式仍可使用,但对 HTML 格式的支持已完全移除。若遇到此类数据文件,需将其转换为纯文本格式才能在 Robot Framework 3.2 或更新版本中使用。最简单的方法是使用 Tidy 工具,但必须使用 Robot Framework 3.1 附带的版本,因为更新版本已完全不支持 HTML 格式。

空格分隔的格式

当 Robot Framework 解析数据时,首先会将数据拆分成行,然后将每行拆分为多个标记(如关键字和参数)。在使用空格分隔格式时,标记之间的分隔符为两个及以上空格,或者一个及以上制表符。除普通的 ASCII 空格外,任何被视为空格的 Unicode 字符(如不间断空格)均可作为分隔符。只要保证至少有两个空格,用作分隔符的空格数量可以变化——这样在配置等场景中就能通过合理对齐数据来提升可读性。

*** Settings ***
Documentation     Example using the space separated format.
Library           OperatingSystem

*** Variables ***
${MESSAGE}        Hello, world!

*** Test Cases ***
My Test
    [Documentation]    Example test.
    Log    ${MESSAGE}
    My Keyword    ${CURDIR}

Another Test
    Should Be Equal    ${MESSAGE}    Hello, world!

*** Keywords ***
My Keyword
    [Arguments]    ${path}
    Directory Should Exist    ${path}

由于制表符和连续空格均被视为分隔符,若需在关键字参数或实际数据中使用这些字符时,必须进行转义处理。可通过特殊转义语法实现,例如:

管道分隔的格式

空格分隔格式的最大痛点在于:关键字与参数的视觉区分较为困难。当关键字需要接收大量参数,或参数本身包含空格时,这一问题尤为突出。此时采用管道分隔格式往往更优,因为管道符能提供更明显的视觉分隔效果。

同一文件可同时包含空格分隔行和管道分隔行。管道分隔行通过行首强制的管道符识别(行尾管道符可选),除行首行尾外,每个管道符两侧必须至少保留一个空格或制表符。虽然不强制要求管道符纵向对齐,但保持对齐能显著提升代码可读性。

| *** Settings ***   |
| Documentation      | Example using the pipe separated format.
| Library            | OperatingSystem

| *** Variables ***  |
| ${MESSAGE}         | Hello, world!

| *** Test Cases *** |                 |               |
| My Test            | [Documentation] | Example test. |
|                    | Log             | ${MESSAGE}    |
|                    | My Keyword      | ${CURDIR}     |
| Another Test       | Should Be Equal | ${MESSAGE}    | Hello, world!

| *** Keywords ***   |                        |         |
| My Keyword         | [Arguments]            | ${path} |
|                    | Directory Should Exist | ${path} |

在使用管道分隔格式时,参数内部的连续空格或制表符无需转义处理。同样,空列通常也无需转义——除非位于行末。但需特别注意:若实际测试数据中包含被空格包围的管道符( | ),则必须使用反斜杠进行转义。

| *** Test Cases *** |                 |                 |                      |
| Escaping Pipe      | ${file count} = | Execute Command | ls -1 *.txt \| wc -l |
|                    | Should Be Equal | ${file count}   | 42                   |

reStructuredText 格式

reStructuredText(reST)是一种易读的纯文本标记语法,常用于 Python 项目的文档编写,包括 Python 官方文档及本用户指南。reST 文档通常被编译为 HTML 格式,同时也支持其他输出格式。将 reST 与 Robot Framework 结合使用,既能编写格式丰富的文档,又能以简洁的文本格式保存测试数据,便于通过简易文本编辑器、差异比对工具和版本控制系统进行操作。

在 Robot Framework 与 reStructuredText 文件结合使用时,常规的 Robot Framework 数据会被嵌入到所谓的代码块(code blocks)中。标准的 reST 代码块使用 code 指令进行标记,但 Robot Framework 同时支持 Sphinx 工具所使用的 code-blocksourcecode 指令格式。

reStructuredText example


code 块之外的文字会被忽略。

.. code:: robotframework

   *** Settings ***
   Documentation    Example using the reStructuredText format.
   Library          OperatingSystem

   *** Variables ***
   ${MESSAGE}       Hello, world!

   *** Test Cases ***
   My Test
       [Documentation]    Example test.
       Log    ${MESSAGE}
       My Keyword    ${CURDIR}

   Another Test
       Should Be Equal    ${MESSAGE}    Hello, world!

此段文本同样位于代码块之外,将被忽略。不包含 Robot Framework 数据的代码块也会被忽略。

.. code:: robotframework

   # Both space and pipe separated formats are supported.

   | *** Keywords ***  |                        |         |
   | My Keyword        | [Arguments]            | ${path} |
   |                   | Directory Should Exist | ${path} |

.. code:: python

   # This code block is ignored.
   def example():
       print('Hello, world!')

Robot Framework 支持使用以下扩展名的 reStructuredText 文件:

为避免解析无关的 reStructuredText 文件,默认情况下执行目录时仅会解析 .robot.rst 扩展名的文件。如需解析其他扩展名的文件,可通过以下任一命令行选项启用:

当 Robot Framework 解析 reStructuredText 文件时,会忽略低于 SEVERE 级别的错误,以避免因非标准指令等标记产生的干扰信息。虽然这可能掩盖部分真实错误,但这些错误在使用标准 reStructuredText 工具处理文件时仍可被发现。

JSON 格式

Robot Framework 同时支持 JSON 格式的数据文件。该格式主要面向工具开发者而非普通用户,且不建议手动编辑。其主要应用场景包括:

把套件转换为 JSON 格式

可通过 TestSuite.to_json 方法将测试套件结构序列化为 JSON 格式。该方法在不带参数调用时,会以字符串形式返回 JSON 数据;同时也支持接收文件路径或已打开的文件对象作为写入目标,并可通过配置选项调整 JSON 格式输出:

from robot.running import TestSuite


# 基于文件系统中的数据创建测试套件
suite = TestSuite.from_file_system('/path/to/data')

# 以字符串形式获取 JSON 数据
data = suite.to_json()

# 使用自定义缩进格式将 JSON 数据保存至文件
suite.to_json('data.rbt', indent=2)

若你更倾向使用 Python 原生数据结构,并自行转换为 JSON 或其他格式,可改用 TestSuite.to_dict 方法实现。

从 JSON 格式转换成套件

可通过 TestSuite.from_json 方法基于 JSON 数据构建测试套件,该方法同时支持以下两种输入形式:

from robot.running import TestSuite


# 从 JSON 文件创建测试套件
suite = TestSuite.from_json('data.rbt')

# 从 JSON 字符串创建测试套件
suite = TestSuite.from_json('{"name": "Suite", "tests": [{"name": "Test"}]}')

# 执行测试套件(注意:需单独生成日志和报告)
suite.run(output='example.xml')

若已有 Python 字典格式的数据,可改用 TestSuite.from_dict 方法。无论采用何种方式重建测试套件,其结果仅存在于内存中,不会在文件系统重建原始数据文件。

如上述示例所示,可通过 TestSuite.run 方法执行创建的测试套件。但直接执行 JSON 文件可能更为简便,具体方法将在下节说明。

执行 JSON 文件

通过 robot 命令执行测试或任务时,系统会自动解析采用自定义 .rbt 扩展名的 JSON 文件,包括以下两种场景:

若需使用标准 .json 扩展名,则需额外配置待解析文件。

调整套件源

通过 TestSuite.to_jsonTestSuite.to_dict 获取的数据中,套件源路径(suite source)采用绝对路径格式。若后续在不同机器上重建套件,源路径可能与目标机器的目录结构不匹配。为解决此问题,可先使用 TestSuite.adjust_source 方法将套件源转为相对路径再获取数据,待套件重建后补充正确的根目录路径:

from robot.running import TestSuite


# 创建测试套件 -> 调整源路径 -> 转换为JSON格式
suite = TestSuite.from_file_system('/path/to/data')  # 从文件系统加载原始套件
suite.adjust_source(relative_to='/path/to')          # 将源路径转换为相对于指定目录的路径
suite.to_json('data.rbt')                            # 序列化为JSON文件

# 在其他环境重建套件并相应调整源路径
suite = TestSuite.from_json('data.rbt')             # 从JSON文件重建套件
suite.adjust_source(root='/new/path/to')            # 根据新环境设置根目录路径

JSON 结构

在生成的 JSON 数据中,测试套件文件中的以下元素将与测试用例/任务一同被包含:导入项、变量、关键字。具体 JSON 结构规范详见 running.json schema文件。

解析测试数据的规则

忽略数据

Robot Framework 解析测试数据文件时会自动忽略以下内容:

Robot Framework 忽略的数据将不会出现在任何结果报告中,且大多数配套工具也会忽略这些数据。如需在输出中显示信息,请将其放入测试用例或套件的文档或其他元数据中,或使用 BuiltIn 关键字 Log 或 Comment 进行记录。

转义

Robot Framework 测试数据中的转义字符是反斜杠(\),此外内置变量 ${EMPTY}${SPACE} 也常用于转义操作。不同转义机制的具体用法将在后续章节详细讨论。

转义特殊字符

反斜杠字符(\)可用于转义特殊字符,使其保留字面值。

转义字符 功能说明 示例代码
\$ 避免被识别为标量变量起始符 ${notvar}
\@ 避免被识别为列表变量起始符 @{notvar}
\& 避免被识别为字典变量起始符 &{notvar}
\% 避免被识别为环境变量起始符 %{notvar}
\# 避免被识别为注释起始符 # not comment
\= 避免被识别为命名参数语法 not=named
| 在管道分隔格式中不作为分隔符 ls -1 *.txt | wc -l
\\ 作为普通字符使用(不进行转义) c:\\temp, \\${var}

构建转义序列

反斜杠字符(\)还可用于创建特殊转义序列,这些序列会被解析为测试数据中难以直接输入的字符。

转义序列 说明 示例
\n 换行符 first line\n2nd line
\r 回车符 text\rmore text
\t 制表符 text\tmore text
\xhh 十六进制值字符(2位) 空字符:\x00
ä:\xE4
\uhhhh 十六进制值字符(4位) 雪人符号:\u2603
\Uhhhhhhhh 十六进制值字符(8位) 爱情酒店符号:\U0001f3e9

处理空值

在使用空格分隔格式时,用作分隔符的空格数量可以变化,因此除非进行转义处理,否则无法识别空值。空单元格可通过反斜杠字符或内置变量 ${EMPTY} 进行转义。通常推荐使用后者,因为更易于理解。

*** Test Cases ***
Using backslash
    Do Something    first arg    \
    Do Something    \            second arg

Using ${EMPTY}
    Do Something    first arg    ${EMPTY}
    Do Something    ${EMPTY}     second arg

在使用竖线分隔格式时,空值仅当位于行末时才需要进行转义:

| *** Test Cases *** |              |           |            |
| Using backslash    | Do Something | first arg | \          |
|                    | Do Something |           | second arg |
|                    |              |           |            |
| Using ${EMPTY}     | Do Something | first arg | ${EMPTY}   |
|                    | Do Something |           | second arg |

处理空格

在关键字参数或其他情况下,空格(尤其是连续空格)会引发问题,主要原因有二:

此时必须对空格进行转义处理。与空值转义方式类似,既可使用反斜杠字符(\),也可调用内置变量 ${SPACE} 实现转义。

反斜杠转义方式 ${SPACE}变量转义方式 技术说明
\ leading space ${SPACE}leading space 前导空格转义
trailing space \ trailing space${SPACE} 反斜杠必须跟在空格后
\ \ ${SPACE} 需在两侧使用反斜杠
consecutive \ \ spaces consecutive${SPACE * 3}spaces 使用扩展变量语法

如上述示例所示,使用 ${SPACE} 变量通常能让测试数据更易于理解。当需要多个空格时,结合扩展变量语法使用尤为方便。

将数据分成多行

当数据过长无法完整显示在一行时,可通过省略号(...)进行分行处理。省略号可采用与起始行相同的缩进格式,且其后必须跟随常规的测试数据分隔符。

在多数情况下,分行数据与未分行数据具有完全相同的语义。但套件文档、测试用例文档、关键字文档以及套件元数据除外 —— 这些内容的分行值会自动以换行符连接,便于创建多行文本值。

... 语法同样适用于变量表中的变量分行。当长标量变量(如 ${STRING})被分割至多行时,最终值将通过行间拼接获得,默认以空格作为分隔符。如需更改分隔方式,可在值前添加 SEPARATOR=<sep> 声明。

以下两个示例展示了包含完全相同数据的不分行与分行处理方案:

*** Settings ***
Documentation      Here we have documentation for this suite.\nDocumentation is often quite long.\n\nIt can also contain multiple paragraphs.
Test Tags          test tag 1    test tag 2    test tag 3    test tag 4    test tag 5

*** Variables ***
${STRING}          This is a long string. It has multiple sentences. It does not have newlines.
${MULTILINE}       This is a long multiline string.\nThis is the second line.\nThis is the third and the last line.
@{LIST}            this     list     is    quite    long     and    items in it can also be long
&{DICT}            first=This value is pretty long.    second=This value is even longer. It has two sentences.

*** Test Cases ***
Example
    [Tags]    you    probably    do    not    have    this    many    tags    in    real    life
    Do X    first argument    second argument    third argument    fourth argument    fifth argument    sixth argument
    ${var} =    Get X    first argument passed to this keyword is pretty long    second argument passed to this keyword is long too
*** Settings ***
Documentation      Here we have documentation for this suite.
...                Documentation is often quite long.
...
...                It can also contain multiple paragraphs.
Test Tags          test tag 1    test tag 2    test tag 3
...                test tag 4    test tag 5

*** Variables ***
${STRING}          This is a long string.
...                It has multiple sentences.
...                It does not have newlines.
${MULTILINE}       SEPARATOR=\n
...                This is a long multiline string.
...                This is the second line.
...                This is the third and the last line.
@{LIST}            this     list     is      quite    long     and
...                items in it can also be long
&{DICT}            first=This value is pretty long.
...                second=This value is even longer. It has two sentences.

*** Test Cases ***
Example
    [Tags]    you    probably    do    not    have    this    many
    ...       tags    in    real    life
    Do X    first argument    second argument    third argument
    ...    fourth argument    fifth argument    sixth argument
    ${var} =    Get X
    ...    first argument passed to this keyword is pretty long
    ...    second argument passed to this keyword is long too

本地化

Robot Framework 的本地化工作始于 6.0 版本,该版本支持翻译以下内容:

未来计划进一步扩展本地化支持范围,例如扩展到日志和报告模块,并可能包含控制结构。

启用语言支持

使用命令行开启

激活语言支持的主要方式是通过命令行使用 --language 选项进行指定。对于内置语言,既可使用语言名称(如 Finnish)也可使用语言代码(如 fi)。名称和代码均不区分大小写及空格,连字符(-)也会被忽略。如需启用多语言支持,需多次使用 --language 选项:

robot --language Finnish testit.robot
robot --language pt --language ptbr testes.robot

--language 选项同样适用于激活自定义语言文件。此时参数值可以是文件路径,若文件位于模块搜索路径中,也可直接使用模块名:

robot --language Custom.py tests.robot
robot --language MyLang tests.robot

出于向后兼容性考虑,以及支持部分翻译场景,系统会始终自动激活英语支持。未来版本可能会提供禁用该特性的选项。

文件预配置

还可以直接在数据文件中通过在任何节标题前添加一行 Language: <value>(不区分大小写)来启用语言。冒号后的值与 --language 选项的解析方式相同:

Language: Finnish

*** Asetukset ***
Dokumentaatio        Finnish language example.

若需启用多语言,可重复 Language: 行。此类配置行不可置于注释中,因此类似 # Language: Finnish 的写法无效。

由于技术限制,单文件语言配置会影响后续文件的解析及整个执行过程。此行为未来可能变更,请勿依赖该特性。若使用单文件配置,请确保所有文件统一使用该方式,或通过 --language 选项全局启用语言。

内置语言支持

自定义语言文件

若所需语言未内置,或需为特定需求创建完全自定义的语言,你可以轻松创建自定义语言文件。语言文件是 Python 文件,内含一个或多个语言定义——启用该文件时将加载所有定义。语言定义通过继承 robot.api.Language 基类并按需覆盖类属性来实现:

from robot.api import Language

class Example(Language):
    test_cases_header = 'Validations'      
    tags_setting = 'Labels'                
    given_prefixes = ['Assuming']         
    true_strings = ['OK', '\N{THUMBS UP SIGN}']  

假设上述代码保存在 example.py 文件中,启用语言文件时只需提供该文件路径或模块名 example 即可。

此示例仅实现了部分可翻译项(因英语会默认启用)。多数属性需指定为字符串,但BDD前缀和真/假值字符串允许使用列表形式定义多个值。更多示例可参考 Robot Framework 内置的 languages 模块——该模块包含 Language 类及所有内置语言定义。

风格

Robot Framework 的语法构建了一种简易编程语言,与其他编程语言类似,代码风格的规范性至关重要。虽然 Robot Framework 的语法设计具有高度灵活性,但仍存在一些普遍推荐的规范:

目前尚未形成强约束规范的场景是关键字的命名格式。Robot Framework 官方文档通常采用首字母大写形式(如 Example Keyword),该风格在测试数据中也较为常见。但对于较长的句子型关键字(例如 Log into system as an admin),这种格式可能不够理想。

建议使用 Robot Framework 的团队制定专属编码规范。社区开发的《Robot Framework 风格指南》可作为优质基准模板,支持按需调整。此外,可通过 Robocop 静态检查工具和 Robotidy 代码格式化工具强制实施这些规范。

lyyyuna 沪ICP备2025110782号-1