基础语法

本章介绍Robot Framework中所有测试数据的语法. 接下来的章节会依次介绍如何创建测试用例, 测试套件等.

文件和目录

测试用例的层次结构是按照如下的方式组织的:

  • 测试用例在 测试用例文件 中.
  • 一个测试用例文件自动创建 测试套件, 该套件包含文件中所有的用例
  • 包含测试用例文件的文件夹组成一个更高层次的测试套件. 测试套件文件夹 中的用例文件是其子套件
  • 目录测试套件可以包含其它的目录, 以此类推.
  • 测试套件目录可以包含一个特殊的 初始化文件.

除了用例和测试套件, 还有几个核心概念:

文件格式

Robot Framework的测试数据以表格的格式定义. 实际标记表格的格式有多种, 包括: HTML格式, tab分隔的TSV格式, 纯文本格式, reStructuredText (reST)格式. 这些具体格式的细节以及各自的优势和问题, 在下面的章节会一一介绍. 具体使用何种格式取决于实际情况, 如果没有特殊需求的推荐使用纯文本格式.

Robot Framework通过文件的扩展名来选择使用何种解析器. 扩展名不分大小写. 可以识别的扩展名包括:

  • HTML: .html, .htm.xhtml
  • TSV: .tsv
  • 纯文本: .txt 和特殊的 .robot
  • reStructuredText: .rst.rest

对于HTML和TSV格式, 可以使用 测试数据模板 来简化一定的工作.

注解

特别的文件扩展名 .robot 从Robot Framework 2.7.6版本后开始支持.

提示

译者注: 对于习惯了使用 RIDE 的用户来说可以略过某些格式的细节介绍. 对于Robot Framework的初学者来说, 有必要至少了解一种文本格式.

HTML格式

HTML文件可以在表格外有其它格式或文本存在. 这样可以在测试用例文件中添加额外的信息, 使得测试用例文件看起来就跟正式的测试规范文档一样. 使用HTML格式最大的问题是编辑起来不容易, 另一个问题是HTML文件在版本控制系统中使用不便, 因为每次变更除了测试数据的变化还会包含HTML标记的变化.

HTML文件中, 测试数据定义在各自独立的表格中. Robot Framework通过第一个单元格的文字来识别区分这些 测试数据表格. 所有没被识别的表格最终都会被忽略.

HTML格式的表格
Setting Value Value Value
Library OperatingSystem    
     
Variable Value Value Value
${MESSAGE} Hello, world!    
     
Test Case Action Argument Argument
My Test [Documentation] Example test  
Log ${MESSAGE}  
My Keyword /tmp  
     
Another Test Should Be Equal ${MESSAGE} Hello, world!
Keyword Action Argument Argument
My Keyword [Arguments] ${path}  
Directory Should Exist ${path}  

编辑测试数据

HTML文件中测试数据的编辑可以使用任意的编辑器, 不过还是推荐使用图形编辑器, 可以直观的看到表格. RIDE 支持HTML文件的读写, 不过遗憾的是, 它会把其它格式和表格外的数据丢弃掉.

编码和实体引用

HTML文件中实体引用 (例如, ä) 也是支持的. 并且支持任意的文件编码格式. 不过HTML文件中必须使用META元素来指定编码, 例如:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

XHTML 文件则应该使用 XML 格式的序文, 例如:

<?xml version="1.0" encoding="Big5"?>

如果没有指定编码, Robot Framework 默认使用 ISO-8859-1.

TSV格式

TSV 文件可以通过电子表格软件(例如Excel)来编辑, 因为其语法简单, 所以可以很轻松地使用程序自动生成. 同时TSV还可以很容易地在普通文本编辑器中编辑, 因此对版本控制系统也比较友好. 不过在这方面 纯文本格式 更胜一筹.

TSV文件中, 所有的数据都存在一张大表中, 不同的 表格 通过星号(*) 来识别, 一个或多个星号后面跟着表名, 最后还可以跟上一个结束星号(后面的这个是可选的).

和HTML格式的处理方式类似, 在第一个表格被识别之前的所有数据, 会被忽略.

TSV格式
*Setting* *Value* *Value* *Value*
Library OperatingSystem    
     
     
*Variable* *Value* *Value* *Value*
${MESSAGE} Hello, world!    
     
     
*Test Case* *Action* *Argument* *Argument*
My Test [Documentation] Example test  
Log ${MESSAGE}  
My Keyword /tmp  
     
Another Test Should Be Equal ${MESSAGE} Hello, world!
     
     
*Keyword* *Action* *Argument* *Argument*
My Keyword [Arguments] ${path}  
Directory Should Exist ${path}  

编辑测试数据

可以使用多种电子表格程序来编辑TSV文件. 记得在保存文件时选择”以tab分隔”的格式, 并将文件扩展名设置为 .tsv. 同时, 建议关闭所有的自动纠错设置, 并且将所有单元格的格式都设置为文本格式.

TSV文件相对容易编辑, 特别当编辑器支持可视的区分Tab和空格时. RIDE 也支持TSV格式.

Robot Framework 解析TSV格式的数据时, 首先按行分割, 然后将行按照制表符分为单元格. 电子表格程序有时会给单元格中的数据裹上引号(例如: "my value"), 如果数据本身含有引号, 其中会写两次(例如: "my ""quoted"" value"), Robot Framework可以正确的处理这种情况. 如果你是通过软件来创建这些数据, 不用操心太多, 但是如果是通过程序生成的数据, 对于引号的处理要参照软件的实现一样.

文件编码

TSV 文件总是按照UTF-8编码来处理, 因为ASCII编码是UTF-8的子集, 所以自然也是支持的.

纯文本格式

纯文本格式非常容易使用文本编辑器来编辑, 同时在版本控制系统中运行良好. 由于这些优势, 纯文本格式是Robot Framework中最常用的一种数据格式.

纯文本格式技术上讲和 TSV格式 有些类似, 区别在于其中用来分隔单元格的方式不同. TSV使用制表符(Tab), 而纯文本使用两个或更多的空格, 还可以使用前后都有空格的管道符(a | b).

测试数据表格 必须在名称前有一个或者多个星号, 这一点和TSV格式类似. 表头中多余的星号和空格都会忽略, 例如, *** Settings ****Settings 效果完全一样.

同样类似于TSV格式, 第一个表格前的所有数据都会被忽略.

在解析纯文本文件时, 制表符(Tab)会自动转换成两个空格, 这样就可以像在TSV文件中那样在纯文本格式中使用Tab作为分隔. 不过需要注意的是, 多个tab在纯文本格式文件也只会被当作一个分隔符, 而在TSV格式中, 每个tab就是一个分隔符.

空格分隔的格式

使用空格分隔时, 空格的数量是不定的, 最少需要2个, 可以尽量将数据对齐的更好看点. 当使用文本编辑器时, 这点相对TSV格式来说是一大优势, 因为TSV的对齐没法控制.

*** Settings ***
Library       OperatingSystem

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

*** Test Cases ***
My Test
    [Documentation]    Example test
    Log    ${MESSAGE}
    My Keyword    /tmp

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

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

因为空格被用作了分隔符, 所以所有空单元格必须要 经过转义 才行. 空格可以用 ${EMPTY} 变量, 也可以用一个反斜杠(\)表示. 其它测试数据中的 空格处理 没什么不同, 该转义的(包括前置或后缀的空格, 连续的空格)还是需要转义.

小技巧

关键字和参数之间推荐使用4个空格隔开.

竖线加空格的分隔方式

使用空格分隔的最大的问题是, 视觉上分隔关键字和参数有时候会比较困难. 特别是关键字中包含空格, 同时包含很多参数, 参数中也可能包含了空格. 这种情况下, 使用竖线加空格的方式来划定分界线更好, 使得单元格的边界视觉上更清晰, 容易区分.

| *Setting*  |     *Value*     |
| Library    | OperatingSystem |

| *Variable* |     *Value*     |
| ${MESSAGE} | Hello, world!   |

| *Test Case*  | *Action*        | *Argument*   |
| My Test      | [Documentation] | Example test |
|              | Log             | ${MESSAGE}   |
|              | My Keyword      | /tmp         |
| Another Test | Should Be Equal | ${MESSAGE}   | Hello, world!

| *Keyword*  |
| 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                   |

编辑和编码

相对于HTML和TSV, 使用纯文本格式的最大好处是可以很容易的使用普通文本编辑器进行编辑. 很多编辑器和IDE(例如Eclipse, Emacs, Vim, and TextMate)都有相应的插件, 可以对Robot Framework的测试数据实现语法高亮显示, 有的还有更高级的特性, 比如关键字自动补全. RIDE 同样支持纯文本格式.

类似于TSV文件, 纯文本格式总是使用UTF-8编码.

可识别的文件扩展名

从Robot Framework 2.7.6版本开始, 可以将纯文本格式的数据文件保存为特定的 .robot 扩展名, 而不是普通的 .txt. 新的扩展名可以更容易的区分测试数据文件和其它的文本文件.

reStructuredText格式

reStructuredText (reST) 是一个易读的纯文本标记语言, 广泛用在Python项目的文档编写上(包括Python自己的官方文档, 也包括本手册). reST一般最终会编译输出为HTML格式, 同时还支持其它多种格式.

在Robot Framework中使用reST可以让你在一个简明的文本格式文件中, 混合使用带富格式的文档和测试数据. 因为也是文本格式, 所以使用文本编辑器, 对比工具, 和版本控制都很方便. 总之, reST结合了很多纯文本和HTML格式的优势.

当使用reST文件时, 可以有两种方式来定义测试数据. 要么使用 代码块 的方式, 在代码块之中仍然采用 纯文本格式 中的格式定义测试用例. 要么使用和在 HTML格式 中一样使用 表格 格式.

注解

在Robot Framework中使用reST文件需要安装Python的 docutils 模块.

代码块

reStructuredText文档以一种称之为代码块的方式来表示一段代码示例. 当reST文档转换成HTML或其它格式时, 代码块中的内容使用 Pygments 进行语法高亮. 标准reST语法中, 代码块使用 code 指令(directive), 但是 Sphinx 使用 code-blocksourcecode. 其中代码的语言名作为参数提供给指令. 例如, 下面的代码块分别包含Python和Robot Framework的例子:

.. code:: python

   def example_keyword():
       print 'Hello, world!'

.. code:: robotframework

   *** Test Cases ***
   Example Test
       Example Keyword

当Robot Framework解析reST文件时, 首先开始查找可能包含了测试数据的 code, code-blocksourcecode 代码块. 如果找到了, 其中的数据会被写入内存中的文件并执行. 代码块之外的其它数据被忽略.

代码块内的测试数据内容必须使用 纯文本格式 定义的.

如下例所示, 空格分隔和竖线分隔都是支持的.

Example
-------

This text is outside code blocks and thus ignored.
这段在代码块之外的文字将被忽略.

.. code:: robotframework

   *** Settings ***
   Library       OperatingSystem

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

   *** Test Cases ***
   My Test
       [Documentation]    Example test
       Log    ${MESSAGE}
       My Keyword    /tmp

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

这段话在代码块之外, 所以会被忽略. 上面使用了空格分隔的格式.
下面的代码块使用的是竖线分隔的格式.

.. code:: robotframework

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

注解

此格式正常使用反斜杠 转义, 无需像reST表格那样二次转义.

注解

使用代码块的方式是Robot Framework 2.8.2才出现的新特性.

使用表格

如果reStructuredText文档没有包含Robot Framework数据的代码块, 则和 HTML格式 一样检查是否有包含数据的表格. 这种情况下, Robot Framework在内存中将文档转换为HTML, 然后按照正常HTML文件的方式继续解析.

Robot Framework靠第一个单元格的内容来标示 测试数据表格, 被识别的表格外的其它内容都被忽略. 下面的例子展示了4种测试数据表格, 既使用了简单的表格语法, 也使用了网格(grid)表格语法:

Example
-------

This text is outside tables and thus ignored.

============  ================  =======  =======
  Setting          Value         Value    Value
============  ================  =======  =======
Library       OperatingSystem
============  ================  =======  =======


============  ================  =======  =======
  Variable         Value         Value    Value
============  ================  =======  =======
${MESSAGE}    Hello, world!
============  ================  =======  =======


=============  ==================  ============  =============
  Test Case          Action          Argument      Argument
=============  ==================  ============  =============
My Test        [Documentation]     Example test
\              Log                 ${MESSAGE}
\              My Keyword          /tmp
\
Another Test   Should Be Equal     ${MESSAGE}    Hello, world!
=============  ==================  ============  =============

Also this text is outside tables and ignored. Above tables are created
using the simple table syntax and the table below uses the grid table
approach.

+-------------+------------------------+------------+------------+
|   Keyword   |         Action         |  Argument  |  Argument  |
+-------------+------------------------+------------+------------+
| My Keyword  | [Arguments]            | ${path}    |            |
+-------------+------------------------+------------+------------+
|             | Directory Should Exist | ${path}    |            |
+-------------+------------------------+------------+------------+

注解

使用简单表格时, 第一列的空单元格需要转义. 例子中用的是反斜杠 \, 还可以使用两个点号 .. .

注解

因为反斜杠在reST中是转义字符, 如果要指定并显示一个反斜杠自身, 需要额外再加一个反斜杠. 例如, 换行字符必须写作 \\n. 同时反斜杠在Robot Framework的数据中也用作转义符, 所以要在测试数据中表示一个字面上的反斜杠需要二次转义, 如 c:\\\\temp.

每次运行时都要把reST文件转换为HTML文件, 显然这会带来额外的损耗. 如果想规避这个问题, 最好是使用其它外部工具先将reST文件转换为HTML, 让Robot Framework使用生成后的文件.

编辑和编码

reStructuredText文件可以使用任何文本编辑器, 很多编辑器和IDE都提供了语法高亮功能. 但是, RIDE 并不支持reST格式.

如果reST文件中包含non-ASCII字符, 则文件需要保存为UTF-8编码格式.

reST源文件中的语法错误

如果一个reStructuredText文档中的语法有错误(比如表格格式不正确), 则解析会失败, 其中的用例也不会执行. 当执行单个reST文件时, Robot Framework会在控制台显示错误信息. 但是在执行一个目录时, 这种解析错误一般会被忽略.

从Robot Framework2.9.2版本开始, 当运行测试时, 低于 SEVERE 级别的错误会被忽略, 这样做是为了避免烦人的(可能)与测试无关的错误, 例如包含非法指令或标记等. 当然, 这有可能会隐藏真正的错误, 但是正常处理这些文件时还是可以发现的(译注: 这里说的处理应该是指用其它工具解析reST文件).

测试数据表格

测试数据按结构划分有4种类型, 如下表所列. 这些测试数据表格由表格中第一个单元格标示. 4种表格的名称分别是 Settings, Variables, Test Cases, 和 Keywords. 匹配时不区分大小写, 同时单数形式如 SettingTest Case 也可接受.

各种测试数据表格
Table Used for
Settings
2) 为 创建测试套件test cases 定义元数据
Variables 定义 变量
Test Cases 创建测试用例
Keywords 创建用户关键字

数据的解析规则

被忽略的数据

当Robot Framework解析测试数据时, 以下数据都会被忽略:

  • 所有在第一格中没有匹配 可识别的表格名称 的表格
  • 第一行中除了第一格之外的其它任何数据
  • 第一个表格之前的所有数据, 如果所使用的文档格式允许表格之间存在数据, 这些也会被忽略
  • 所有空行, 这意味着可以使用空行提供表格的可读性
  • 行末的空单元格, 除非已经 被转义.
  • 所有的单个反斜杠(\), 如果其不是用于转义的话
  • 如果井字符(#)是一个单元格的第一个字符, 则所有跟在后面的字符都被忽略, 也就是说可以使用 # 在测试数据中添加注释.
  • HTML/reST格式中其它的标记和格式

如果数据被Robot Framework忽略, 则这些数据不会出现在任何后续的报告中, 并且大部分使用Robot Framework的其它工具也会忽略它们. 如果要添加在输出中可见的信息, 请将它们放在文档中, 或测试用例和套件的其它元数据(metadata)中, 或使用内置的关键字 LogComment 记入日志.

如何处理空格

Robot Framework处理空格的方式和HTML源代码处理空格的方式一样:

  • 换行, 回车, 以及制表符, 都转换为空格.
  • 单元格领头的空格和末尾的空格都会被忽略
  • 多个连续的空格被压缩为一个空格

此外, 非中断空格(non-breaking spaces)被替换为普通空格, 以避免引发难以定位的错误.

如果要用到领头或末尾的空格, 或连续的空格, 它们都 必须被转义.

换行, 回车, 制表符, 和非中断空格则可以分别用 escape sequences \n, \r, \t, and \xA0 来创建.

字符转义

Robot Framework的测试数据使用反斜杠(\\)作为转义字符, 此外还增加了 `built-in variables`_ ${EMPTY}${SPACE} 经常用来作为转义. 不同的转义策略在下面的小节中详细讨论.

转义特殊字符

反斜杠可以用来转义特殊字符, 这样我们就能使用它们的字面值了.

转义特殊字符
Character Meaning Examples
\$ 正常用于 标量变量. \${notvar}
\@ 正常用于 列表变量. \@{notvar}
\% 正常用于 环境变量. \%{notvar}
\# 正常用于 comment. \# not comment
\= 正常用于 命名参数. not\=named
\| 正常用于 竖线加空格的分隔方式. | Run | ps \| grep xxx |
\\ 用于转义. c:\\temp, \\${var}

提示

译注: 上表第2列, 原文是 Dollar sign, never starts a scalar variable., 感觉直译有些奇怪, 所以这里直接给出这些字符的原来作用是什么, 而后面的例子表示 经过转义后, 这些字符就失去了原来的作用.

转义序列

反斜杠还可以用来创建特殊的转义序列(escape sequence), 这些转义序列所代表的意义很难(甚至不可能) 在测试数据中通过普通字符表示.

转义序列
Sequence Meaning Examples
\n Newline character. first line\n2nd line
\r Carriage return character text\rmore text
\t Tab character. text\tmore text
\xhh Character with hex value hh. null byte: \x00, ä: \xE4
\uhhhh Character with hex value hhhh. snowman: \u2603
\Uhhhhhhhh Character with hex value hhhhhhhh. love hotel: \U0001f3e9

注解

在测试数据中的所有字符串, 包括 \x02 这种字符, 都是Unicode. 如果有需要的话, 必须明确地转换. 转换的方法可以使用 BuiltIn_ 关键字 Convert To BytesString_ 库中的 Encode String To Bytes. 或者在Python代码中使用类似于 str(value)value.encode('UTF-8') 的方法.

注解

如果在 \x \u\U 转义符后面跟了非法的十六进制数, 则解析的结果是保留原始的字符, 反斜杠除外. 例如, \xAX (X不是十六进制), \U00110000 (值太大了) 解析的结果分别是 xAXU00110000. 不过, 这种情况可能会在将来有所改变.

注解

如果需要用与操作系统无关的换行符(Windows中是 \r\n, 其它系统是``n``), 可以使用 `Built-in variable`_ ${\n}.

注解

跟在 \n 后面的未经转义的空格会被忽略. 也就是说, two lines\nheretwo lines\n here 是等价的. 这样做的动机是在使用HTML格式时, 能包裹包含换行符的长行, 不过同样的逻辑对其它格式也一样. 该规则的一个特殊情况是在 `extended variable syntax`_ 中的空白符不会忽略.

注解

\x, \u\U 等转义序列在Robot Framework 2.8.2版本新引入.

避免忽略空单元格

如果需要使用空值, 例如作为关键字的参数, 必须明确地转义以避免被框架 忽略. 不管使用哪种数据格式, 空的收尾单元格必须被转义. 当使用 空格分隔的格式 时, 所有的空值都必须被转义.

空的单元格既可以使用反斜杠转义, 也可以使用 内置变量 ${EMPTY}. 特别推荐使用后者, 因为更清楚易懂. 一个特殊情况是在 空格分隔的格式 中使用 FOR循环 时, 缩进的单元格中应使用反斜杠. 所有这些情况都在下面的例子中进行了说明, 先是HTML格式, 然后是空格分隔的纯文本格式:

Test Case Action Argument Argument Argument
Using backslash Do Something first arg \  
Using ${EMPTY} Do Something first arg ${EMPTY}  
Non-trailing empty Do Something   second arg # No escaping needed in HTML
For loop :FOR ${var} IN @{VALUES}
  Log ${var} # No escaping needed here either
*** Test Cases ***
Using backslash
    Do Something    first arg    \
Using ${EMPTY}
    Do Something    first arg    ${EMPTY}
Non-trailing empty
    Do Something    ${EMPTY}     second arg    # Escaping needed in space separated format
For loop
    :FOR    ${var}    IN    @{VALUES}
    \    Log    ${var}                         # Escaping needed here too

避免忽略空格

因为领头的, 收尾的, 以及连续的空格在单元格中都将被 忽略, 如果这些空格有需要保留的话, 例如作为关键字的参数, 则必须经过转义. 和避免忽略空单元格类似, 既可以使用反斜杠, 也可以使用 内置变量 ${SPACE}.

Escaping spaces examples
Escaping with backslash Escaping with ${SPACE} Notes
\ leading space ${SPACE}leading space  
trailing space \ trailing space${SPACE} 反斜杠必须跟在空格后面.
\ \ ${SPACE} 两边都需要反斜杠.
consecutive \ \ spaces consecutive${SPACE * 3}spaces 使用 扩展变量语法

如上例所示, 使用 ${SPACE} 变量是测试数据更容易理解. 当需要不止一个空格时, 结合 扩展变量语法 使用时, 显得尤其方便.

测试数据分为多行

如果数据太多不方便放在一行, 可以另起一行, 下面一行的开头使用省略号(...)来表示继续. 在测试用例和关键字表格中, 省略号的前面必须至少有一个空的单元格(因为第一列只有用例名称). 在设置和变量表格中, 可以直接放在设置或变量名的下方. 在所有类型的表格中, 省略号前面的空单元格都会被忽略.

此外, 某些设置只接受一个值(主要是文档), 这个值也可以分开写在多列. 当解析完毕, 最终将用空格将多列的值拼接起来. 从Robot Framework 2.7版本开始, 这些值如果分为多行, 将使用 换行符将多行拼接起来.

上面讨论的语法都通过下面的例子来解释说明. 前3个表格中的数据没有分割, 接下来的3个表格展示了如何将数据分割为多行以占用更少的列数.

没有进行分割的数据
Setting Value Value Value Value Value Value
Default Tags tag-1 tag-2 tag-3 tag-4 tag-5 tag-6
Variable Value Value Value Value Value Value
@{LIST} this list has quite many items
Test Case Action Argument Arg Arg Arg Arg Arg Arg
Example [Documentation] Documentation for this test case.\n This can get quite long...            
  [Tags] t-1 t-2 t-3 t-4 t-5    
  Do X one two three four five six  
  ${var} = Get X 1 2 3 4 5 6
分割为多行的测试数据
Setting Value Value Value
Default Tags tag-1 tag-2 tag-3
... tag-4 tag-5 tag-6
Variable Value Value Value
@{LIST} this list has
... quite many items
Test Case Action Argument Argument Argument
Example [Documentation] Documentation for this test case.
... This can get quite long...
[Tags] t-1 t-2 t-3
... t-4 t-5  
Do X one two three
... four five six
${var} = Get X 1 2
  ... 3 4
  ... 5 6