创建测试用例

本章介绍整个测试用例的语法. 使用 测试用例文件 将测试用例组织为 测试套件, 以及 测试套件文件夹 将在下一章讨论.

测试用例语法

基础语法

测试用例表格中的测试用例由可用的关键字构造. 关键字可以从 使用测试库资源文件 导入, 也可以在当前测试用例文件中的 关键字表格 创建.

测试用例表格的第一列包含测试用例的名称. 一个用例始于测试用例名, 直到遇到下一个用例名, 或者到表格的结束. 在表格头和第一个测试用例之间不允许有其它数据, 否则将引发错误.

第二列一般情况下是关键字的名称. 当要 从关键字获取返回值 的时候是个特例, 这种情况下第二列, 甚至后续的列都可能是用来接受返回值的变量名称, 关键字名称跟在这些变量后面. 最后, 不论关键字名称位于第几列, 跟在其后的列包含的是要传递给该关键字的参数.

*** Test Cases ***
Valid Login
    Open Login Page
    Input Username    demo
    Input Password    mode
    Submit Credentials
    Welcome Page Should Be Open

Setting Variables
    Do Something    first argument    second argument
    ${value} =    Get Some Value
    Should Be Equal    ${value}    Expected value

测试用例表格中的设置

每个测试用例都可以有自己的相关设置. 设置项名称总是出现在第2列, 它们的值跟在后面的列中. 设置项的名称使用方括号([])括起来, 以区别于关键字.

下面列出了可设置的项, 后面的章节会进行详细的解释.

[Documentation]
用于指定 测试用例文档.
[Tags]
用于指定 测试用例的标签.
[Setup], [Teardown]
用于指定 Setup和Teardown.
[Template]
用于指定 测试模板. 测试用例本身将只包含数据, 每行数据都是传递给该关键字的参数, 最终实现数据驱动的测试.
[Timeout]
用于设置 test case timeout. timeouts 将在独立的章节讨论.

带设置的测试用例示例:

*** Test Cases ***
Test With Settings
    [Documentation]    Another dummy test
    [Tags]    dummy    owner-johndoe
    Log    Hello, world!

使用参数

前面有的例子已经展示了关键字是怎样 接受 不同的参数的, 本节将更具体地讨论这个重要的功能点.

如何 实现 这些带各种参数的 用户关键字库关键字 则在其它独立的章节讨论.

关键字可以接受零到多个参数, 并且有些参数还可以有默认值. 总的来说, 一个关键字可以接受的参数数量和类型取决于它的实现, 一般来讲, 最好的去处是去该关键字的文档中来搜索相关信息.

对本章中的例子而言, 相关的文档可以使用 库文档工具(Libdoc) 工具生成. 不过, 也可是使用其它的文档生成工具, 例如 javadoc.

提示

译注: 调用关键字的传参方式和调用Python函数的语法如出一辙, 所以熟悉Python的小伙伴可以快速掠过本节内容.

必填参数

大多数的关键字有部分参数是必须要传递的. 在关键字的文档中, 这部分参数的表示方式是 first, second, third. 这里的参数名称实际上并不重要, 仅作为描述该参数的意义, 但是参数的个数必须完全一致. 少传或者多传都会导致错误发生.

下面的用例用到了关键字 Create DirectoryCopy File, 两者都来自于 OperatingSystem_ 库. 它们的参数定义分别是 pathsource, destination, 也就是说, 分别需要1个和2个参数. 最后一个关键字, 来自 BuiltIn_No Operation 不接受参数.

*** Test Cases ***
Example
    Create Directory    ${TEMPDIR}/stuff
    Copy File    ${CURDIR}/file.txt    ${TEMPDIR}/stuff
    No Operation

缺省值

可以为参数指定缺省值. 在关键字文档中, 缺省值通常表示为 name=default value, 即使用等于号把参数名和缺省值连接起来.

对于使用Java实现的关键字来说, 意味着同一个关键字, 需要使用不同的参数 多次实现 (实际上就是重载).

所有参数都可以指定缺省值, 不过位置参数 不可以 跟在带缺省值的参数的后面.

使用缺省值的情况见下例, 使用了关键字 Create File, 可接受的参数是 path, content=, encoding=UTF-8. 可以尝试不带任何参数, 或者多于3个参数来调用该关键字, 将会报错.

*** Test Cases ***
Example
    Create File    ${TEMPDIR}/empty.txt
    Create File    ${TEMPDIR}/utf-8.txt         Hyvä esimerkki
    Create File    ${TEMPDIR}/iso-8859-1.txt    Hyvä esimerkki    ISO-8859-1

可变数量的参数

一个关键字还可以接受任意数量的参数, 也就是说, 参数个数是不确定的. 这种类型的参数一般称之为 varargs. varargs可以和必需参数以及带缺省值的参数混合使用, 不过在参数列表中必须排在它们的后面. 在文档中, 此种参数通过在参数名称前加一个星号(*)来表示, 例如 *varargs.

例如, OperatingSystem_ 库中的关键字 Remove FilesJoin Paths, 参数分别是 *pathsbase, *parts. 前者可以接受任意数量的参数, 后者则至少需要一个参数.

*** Test Cases ***
Example
    Remove Files    ${TEMPDIR}/f1.txt    ${TEMPDIR}/f2.txt    ${TEMPDIR}/f3.txt
    @{paths} =    Join Paths    ${TEMPDIR}    f1.txt    f2.txt    f3.txt    f4.txt

命名参数

命名参数语法使 缺省值 参数用起来更加灵活, 因为它可以明确地标示要传递的值对应的是哪个参数. 这种语法格式和Python语言中的 keyword arguments 如出一辙.

基础语法

可以使用 arg=value 的格式来指定传值给某个参数. 当多个参数有默认值时, 这种方式就显得特别有用, 因为我们只需要指定其中一些, 让其余的继续使用默认值.

例如, 如果一个关键字接受参数 arg1=a, arg2=b, arg3=c, 调用时传参 arg3=override, 则参数 arg1arg2 使用默认值, 而 arg3 的值为 override. 这一切说起来颇为啰嗦, 查看下面的 命名参数示例 就比较清楚了.

命名参数语法是大小写敏感和空格敏感的. 前者的意思是, 如果参数名为 arg, 则必须使用 arg=value, 而 Arg=valueARG=value 都是错误的. 后者的意思是, 等号 = 的前面不能有空格, = 后面可以有空格, 这些空格会被视作值的一部分.

当命名参数语法用在 user keywords 时, 参数名称必须去掉 ${} 标示. 例如, ${arg1}=first, ${arg2}=second 必须写成如 arg2=override.

不可以在命名参数后面使用普通的位置参数, 例如 | Keyword | arg=value | positional |. 从Robot Framework 2.8 开始, 这会导致一个明确的错误提示. 命名参数之间的相对位置则无关紧要.

注解

在Robot Framework 2.8版本之前, 不可以针对没有默认值的参数使用命名参数语法.

带变量的命名参数

变量 不但可以用于参数的值, 也可以用于参数名称. 如果变量值是一个单独的 标量变量, 则将按原值传递给关键字. 变量的值可以是任何的对象, 不仅限于字符串. 例如, 调用关键字时使用 arg=${object}, 则变量 ${object} 最终会传递给关键字.

如果将变量用在命名参数的名称上, 变量需要在匹配参数名称之前就被解析出来. 这是2.8.6版本后才有的新功能.

命名参数语法需要在调用关键字时使用字面的等号(=), 也就是说, 不能把 = 放在一个变量里, 例如 foo=bar, 是不可能触发命名参数语法的.

当封装关键字的时候, 这点必须特别注意. 如果上层的关键字接受 可变数量的参数, 也就是 `` @{args}``, 该关键字中调用另一个关键字时把所有的参数都通过 `` @{args}`` 传递过去, 则其中可能包含的 named=arg 将不会被识别. 具体请看下面的例子.

*** Test Cases ***
Example
    Run Program    shell=True    # This will not come as a named argument to Run Process

*** Keywords ***
Run Program
    [Arguments]    @{args}
    Run Process    program.py    @{args}    # Named arguments are not recognized from inside @{args}

如果关键字需要接受并传递任意的命名参数, 它必须改用 任意关键字参数. 参见 Kwargs示例, 这个例子展示了一个封装后的关键字如何既传递位置参数, 又传递命名参数.

转义命名参数语法

只有在参数等号前面的部分匹配上了某个参数名称时, 命名参数语法才起作用. 假如有一个位置参数需要传入一个值 foo=quux, 假设同时有一个参数名是 foo, 此时, 大多数情况也许会触发语法错误, 还可能将 quux 值传递给了参数 foo, 当然也有可能是如我们预期的那样(位置参数接受到了完整的字符串值), 取决于参数的位置顺序等实际情况. 这时候, 需要使用反斜杠转义符来将其中的等号 转义, 如 foo\=quux. 这样, 位置参数将会明确的接受到值 foo=quux.

注意, 如果关键字没有参数名称是 foo, 则这里的转义不是必需的. 不过, 由于这种写法会更明确, 所以推荐的做法是不管什么情况下都转义.

支持命名参数的地方

如前所述, 命名参数语法可以用于关键字. 此外, 它还可以用在 importing libraries.

user keywords 以及大部分的 使用测试库 也都支持命名参数. 唯一的例外是基于Java的 static library API 库. 使用 库文档工具(Libdoc) 生成的库文档中会显示该库是否支持命名参数.

注解

Robot Framework2.8版本之前, 使用 动态库API 的库也不支持命名参数语法.

命名参数示例

下面的例子展示了命名参数语法如何应用在库关键字和用户关键字上, 以及在导入 Telnet 测试库时的应用.

*** Settings ***
Library    Telnet    prompt=$    default_log_level=DEBUG

*** Test Cases ***
Example
    Open connection    10.0.0.42    port=${PORT}    alias=example
    List files    options=-lh
    List files    path=/tmp    options=-l

*** Keywords ***
List files
    [Arguments]    ${path}=.    ${options}=
    Execute command    ls ${options} ${path}

任意命名参数

Robot Framework 2.8加入了对 Python风格的命名参数 <python kwargs> (**kwargs)的支持. 这意味着关键字可以接受任意数量的 name=value 语法格式的参数.

Kwargs和 命名参数 类似, 也支持变量. 实际应用中, 变量既可以作为参数名, 也可以作为参数值, 但是必须明确的使用转义符. 例如, foo=${bar}${foo}=${bar} 都是合法的, 只要这些变量本身没问题. 一个额外的限制是, 作为参数名称的变量值必须是字符串.

注解

支持在参数名称中使用变量是Robot Framework 2.8.6才加入的新功能.

最初 **kwargs 只可用于Python编写的库, 后来Robot Framework 2.8.2扩展到 动态库API, 2.8.3版本继续扩展到支持基于的Java测试库以及 远程测试库接口. 最终, 用户关键字在2.9版本也开始支持 kwargs.

也就是说, 当前最新的版本中, 所有的关键字都可以使用 **kwargs.

Kwargs示例

第1个例子中, 使用了 Process_ 中的 Run Process 关键字. 该关键字的参数签名是: command, *arguments, **configuration, 分别的含义是: command 表示要执行的命令, 命令所需的参数通过 可变数量的参数*arguments 指定, 最后是可选的配置参数 **configuration. 例子中同时展示了kwargs中变量的用法, 就和 使用命名参数 一样.

*** Test Cases ***
Using Kwargs
    Run Process    program.py    arg1    arg2    cwd=/home/user
    Run Process    program.py    argument    shell=True    env=${ENVIRON}

关于如何在自定义的测试库中使用 kwargs 语法, 请参阅: 创建测试库 中的 free keyword arguments (**kwargs) 部分内容.

第2个例子中, 我们封装了一个 user keyword 来简化调用上述的运行 program.py 过程. 封装后的关键字 Run Program 接受任意数量的参数和kwargs, 并将它们传递给底层的关键字 Run Process, 只是固定其中的 command 参数.

*** Test Cases ***
Using Kwargs
    Run Program    arg1    arg2    cwd=/home/user
    Run Program    argument    shell=True    env=${ENVIRON}

*** Keywords ***
Run Program
    [Arguments]    @{arguments}    &{configuration}
    Run Process    program.py    @{arguments}    &{configuration}

关键字名称中嵌入参数

在关键字的名称中嵌入参数是一种全新的指定参数的方式. 这种语法同时被 测试库关键字用户关键字 支持.

失败

测试用例何时失败

一个测试用例中用到的任何一个关键字发生失败, 则该用例也执行失败. 正常情况下, 这表明该测试用例的执行被结束, 如果设置了 Setup和Teardown, 则也会执行. 测试流程继续往下执行下一个用例.

特殊情况下, 如果当发生错误时不想结束测试用例, 可以使用特殊的 可继续的失败.

错误信息

测试用例的错误信息直接来源于失败的关键字. 有些错误信息由关键字直接生成, 有的关键字则允许用户来配置.

在某些情况下, 例如设置了可继续执行的失败, 一个测试用例可能会发生多次的失败, 这时最终的错误信息将由各自的错误信息组合起来. 超长的错误信息在 reports 中会自动截断, 以保持报告的可读性. 完整的信息总是可以在 log 文件中找到.

默认情况下错误信息就是普通的文本, 不过从Robot Framework 2.8版本开始, 错误信息中可以 包含HTML格式. 通过在错误信息的开始部分指定 *HTML* 标记即可启用该功能(该标记本身在最终的错误信息中不会展示).

下面第2个例子中展示了如何使用自定义的HTML格式的消息.

*** Test Cases ***
Normal Error
    Fail    This is a rather boring example...

HTML Error
    ${number} =    Get Number
    Should Be Equal    ${number}    42    *HTML* Number is not my <b>MAGIC</b> number.

测试用例名称和文档

测试用例的名称直接在测试用例表格中指定: 即表格中输入的用例名称是什么就是什么. 一个测试套件中的用例名称必须唯一.

在测试用例中, 可以通过 automatic variable ${TEST_NAME} 来指代当前用例的名称. 这个变量在测试执行的任何阶段都可以访问到, 包括用户关键字, 以及测试准备和测试结束阶段.

配置项 [Documentation] 用来为用例设置一段文档说明. 这个说明会显示在命令行的输出中, 以及后续的测试日志和测试报告中. 文档中可以使用简单的 HTML formatting, 也可以使用 变量, 使文档更加的动态.

如果一个文档被分为多列, 则同一行中每个单元格中的内容最终以空格连接. 如果文档 被分为多行, 则最终的文档 以换行符拼接起来. 如果某行结尾已经有了换行符, 或者使用了 转义的反斜杠, 则不会再添加换行符.

*** Test Cases ***
Simple
    [Documentation]    Simple documentation
    No Operation

Formatting
    [Documentation]    *This is bold*, _this is italic_  and here is a link: http://robotframework.org
    No Operation

Variables
    [Documentation]    Executed at ${HOST} by ${USER}
    No Operation

Splitting
    [Documentation]    This documentation    is split    into multiple columns
    No Operation

Many lines
    [Documentation]    Here we have
    ...                an automatic newline
    No Operation

测试用例拥有一个清楚的, 描述性的名称是非常重要的, 这种情况下一般就不再需要文档说明了. 如果用例的逻辑比较复杂, 以至于必须使用文档才能说清楚, 这往往意味着该用例中的关键字有待改进, 需要使用更好的名称, 而不是添加额外的文档. 最后, 诸如环境或用户信息等这类元数据, 最好使用 测试用例的标签 来指定.

测试用例的标签

Robot Framework的标签功能是一个简单而强大的分类机制. 标签本身就是任意的文本, 它们被用于如下目的:

  • 标签在 reports, logs 以及测试数据中展示, 显示关于测试用例的元数据信息.
  • 用例的 执行统计 (total, passed, failed 就是自动基于标签收集的).
  • 使用标签, 可以 包含或排除 测试用例来执行.
  • 使用标签, 可以指定何种用例是 critical.

本节仅介绍如何针对测试用例设置标签, 几种不同的方式列在下面, 这些方法可以自然地组合.

Force Tags 在Setting表中设置
包含该设置的测试用例文件中所有用例都被指定打上这些标签. 如果这是用在 test suite initialization file, 则下面的所有子测试套件都被打上这些标签.
Default Tags 在Setting表中设置
没有单独设置 [Tags] 的用例将被打上这些默认标签. 默认标签不支持在测试套件的初始化文件中指定.
[Tags] in the Test Case table
每个测试用例各自要打的标签. 如果设置了, 就不再包含 Default Tags, 所以, 可以通过设置一个空值来覆盖默认标签, 亦可以使用 NONE.
--settag 命令行选项
所有通过包含该选项的命令执行的测试用例, 除了已有的标签, 都会再加上选项中指定的标签.
Set Tags, Remove Tags, Fail and Pass Execution 关键字
这些内置的关键字可以用来在测试执行过程中动态的操纵用例的标签.

标签本身就是任意的文本, 但是它们会被标准化: 去除所有空格, 全部转为小写. 如果一个用例打上相同的标签多次, 仅保留第一个. 标签可以使用变量来创建, 只要变量存在即可.

*** Settings ***
Force Tags      req-42
Default Tags    owner-john    smoke

*** Variables ***
${HOST}         10.0.1.42

*** Test Cases ***
No own tags
    [Documentation]    This test has tags owner-john, smoke and req-42.
    No Operation

With own tags
    [Documentation]    This test has tags not_ready, owner-mrx and req-42.
    [Tags]    owner-mrx    not_ready
    No Operation

Own tags with variables
    [Documentation]    This test has tags host-10.0.1.42 and req-42.
    [Tags]    host-${HOST}
    No Operation

Empty own tags
    [Documentation]    This test has only tag req-42.
    [Tags]
    No Operation

Set Tags and Remove Tags Keywords
    [Documentation]    This test has tags mytag and owner-john.
    Set Tags    mytag
    Remove Tags    smoke    req-*

保留的标签

通常情况下, 用户在各自的环境下可以任意使用自定义的标签. 不过, 某些标签名称对Robot Framework来说有特殊的意义, 如果用于其它目的可能会引发不可预测的结果. 所有的特殊标签现在(并且在将来也会)都以前缀 robot- 开始. 为了避免出现问题, 用户应该避免使用带 robot- 前缀的标签, 除非是刻意要使用特殊功能.

目前(3.0版本), 唯一的特殊标签只有 robot-exit, 当使用 优雅地结束测试执行 时, 自动添加该标签到相应的测试.

当然, 将来也许会增加更多的特殊标签.

Setup和Teardown

和很多其他测试自动化框架类似, Robot Framework也有setup和teardown的功能. 简而言之, setup在测试用例之前执行, 而teardown在测试用例之后执行.

在Robot Framework中, setup和teardown都是带参数的普通关键字而已, 并且各自只能指定一个关键字. 如果涉及到多个步骤, 只能创造一个更高层的 user keywords. 另一种解决方案是使用 BuiltIn 关键字 Run Keywords 来执行多个关键字.

Teardown在以下两个方面比较特殊. 首先, 它在测试用例执行失败的时候也会被执行, 所以常常用来作为测试环境的清理工作, 因为不管测试结果如何, 这些清理任务都需要做. 其次, teardown中所有的关键字都会被执行, 哪怕其中有的执行失败. 这种 失败后继续 机制也可以用来普通关键字上, 但是在teardown中, 这是个默认打开的.

为测试用例设置setup或teardown的最简单的方式是在测试用例文件中, 在设置表中指定 Test SetupTest Teardown.

每个单独的用例也可以指定自身的setup或teardown, 在测试用例表中设置 [Setup][Teardown] 即可. 如果用例文件的设置表中已经设置, 则此处设置会覆盖前者. 亦或者设置 [Setup][Teardown] 项为空(可以是空白, 也可以使用特殊的 NONE 值), 则表示当前用例没有setup/teardown.

*** Settings ***
Test Setup       Open Application    App A
Test Teardown    Close Application

*** Test Cases ***
Default values
    [Documentation]    Setup and teardown from setting table
    Do Something

Overridden setup
    [Documentation]    Own setup, teardown from setting table
    [Setup]    Open Application    App B
    Do Something

No teardown
    [Documentation]    Default setup, no teardown at all
    Do Something
    [Teardown]

No teardown 2
    [Documentation]    Setup and teardown can be disabled also with special value NONE
    Do Something
    [Teardown]    NONE

Using variables
    [Documentation]    Setup and teardown specified using variables
    [Setup]    ${SETUP}
    Do Something
    [Teardown]    ${TEARDOWN}

Setup或teardown中指定的关键字名称可以使用变量代替. 这样在不同的环境下, 只需在执行时通过命令行选项指定关键字名称, 就可以使用不同的setup或者teardown.

注解

测试套件可以有自己的setup和teardown. 一个测试套件的setup在其中所有的用例以及所有子套件之前被执行, 而它的 teardown则在最后.

测试模板

测试模板将普通的 keyword-driven 测试转为 data-driven 测试.

关键字驱动的测试用例的内容包含若干步骤, 每个步骤都涉及带若干参数调用关键字, 而包含模板的测试用例的内容只有调用模板关键字所需的参数.

相比较于在一个测试用例(或一个测试用例文件中的多个测试)中多次调用同一个关键字, 这样只需一个测试用例即可搞定.

模板关键字既可以接受普通的位置参数和命名参数, 也可以接受嵌在关键字名称中的参数. 不同于其他设置, 模板的指定不可以使用变量.

基础用法

下面的例子展示了一个接受位置参数的关键字, 是如何作为模板使用的. 其中这两个用例在功能上是完全相同的.

*** Test Cases **
Normal test case
    Example keyword    first argument    second argument

Templated test case
    [Template]    Example keyword
    first argument    second argument

如例中所示, 可以对单个测试用例通过设置 [Template] 指定一个模板. 另一种方式是在测试文件的设置表中设置 Test Template, 这种情况下, 该文件中的所有测试用例都会应用该模板.

如果用例单独设置了 [Template], 则会覆盖文件中的 Test Template, 进而可以为 [Template] 设置空值(空格或 NONE), 表示当前用例没有模板, 即使测试文件设置表中已有设置.

如果一个模板用例的内容有多行数据, 该模板会逐行应用于这些数据. 也就是说, 该模板关键字会被调用多次, 每次使用其中一行的数据作为参数.

模板测试用例在执行过程中, 如果有某一轮次执行失败也不会影响下面轮次继续执行. 也就是说, 对于普通测试用例需要单独设置的 失败后继续 特性, 对于模板测试用例来说是自动启用的.

*** Settings ***
Test Template    Example keyword

*** Test Cases ***
Templated test case
    first round 1     first round 2
    second round 1    second round 2
    third round 1     third round 2

对模板来说, 各种参数, 包括 缺省值, 可变数量的参数, 命名参数任意关键字参数, 都和平常一样使用. 参数中的 变量 也同样支持.

使用内嵌参数的模板

从Robot Framework 2.8.2版本开始, 模板支持一种变种的 关键字名称中嵌入参数.

对于模板来说, 如果模板关键字名称中包含变量, 则这些变量会被视作参数的占位符, 最终在执行时被实际参数替代. 最终的关键字也不再需要其它的参数了. 如下例所示:

*** Test Cases ***
Normal test case with embedded arguments
    The result of 1 + 1 should be 2
    The result of 1 + 2 should be 3

Template with embedded arguments
    [Template]    The result of ${calculation} should be ${expected}
    1 + 1    2
    1 + 2    3

*** Keywords ***
The result of ${calculation} should be ${expected}
    ${result} =    Calculate    ${calculation}
    Should Be Equal    ${result}     ${expected}

当模板中使用了嵌入式的参数, 模板关键字中参数的个数必须和传入的参数个数一致, 但是参数的名称不一定非要和原关键字保持一致. 甚至还可以添加或减少参数, 如下例所示:

*** Test Cases ***
Different argument names
    [Template]    The result of ${foo} should be ${bar}
    1 + 1    2
    1 + 2    3

Only some arguments
    [Template]    The result of ${calculation} should be 3
    1 + 2
    4 - 1

New arguments
    [Template]    The ${meaning} of ${life} should be 42
    result    21 * 2

在模板中使用嵌入式参数的主要好处是参数名称都被明确指定. 当使用普通参数时, 也可以通过给列命名来达成同样的效果. 这会在后续章节 数据驱动型 中介绍.

带for循环的模板

如果模板用例中使用了 for loops, 该模板会应用于for循环中每一次的循环. 并且遇到错误也会继续执行. 也就是说, 用例中每一步骤中的每次循环都会被执行.

最好还是来看例子:

*** Test Cases ***
Template and for
    [Template]    Example keyword
    :FOR    ${item}    IN    @{ITEMS}
    \    ${item}    2nd arg
    :FOR    ${index}    IN RANGE    42
    \    1st arg    ${index}

不同的测试用例风格

有几种不同的测试用例的写法. 用来描述某些 工作流 的用例一般是关键字驱动或行为驱动型. 数据驱动型则是针对同一个工作流, 使用不同的输入数据.

关键字驱动型

针对工作流的测试, 例如 Valid Login 流程, 由若干关键字和相应的参数组成.

前例 所示, 关键字驱动型的用例的通常结构是, 系统先进入到一个初始状态(Open Login Page), 然后对系统进行某些操作(Input Name, Input Password, Submit Credentials), 最后校验系统的表现是否符合预期(Welcome Page Should Be Open).

数据驱动型

数据驱动型的测试方法中, 测试用例仅使用一个高级别的关键字, 通常是创建的 user keyword, 该关键字中则隐藏了实际的流程.

这种测试对于要针对某个相同的测试场景使用不同的输入/输出时非常有用. 虽然可以在每个测试用例中都重复调用一次相同的关键字, 但是使用 test template 功能更加简便, 因为关键字只需要指定一次.

*** Settings ***
Test Template    Login with invalid credentials should fail

*** Test Cases ***                USERNAME         PASSWORD
Invalid User Name                 invalid          ${VALID PASSWORD}
Invalid Password                  ${VALID USER}    invalid
Invalid User Name and Password    invalid          invalid
Empty User Name                   ${EMPTY}         ${VALID PASSWORD}
Empty Password                    ${VALID USER}    ${EMPTY}
Empty User Name and Password      ${EMPTY}         ${EMPTY}

小技巧

如上例所示, 给列命名使得测试用例更易读易懂. 这种方法之所以可行, 是因为对用例表的表头那一行, 除了第一格中的数据, 其它的内容都是 被忽略的

上例中包含了6个独立的测试, 每次都是非法 用户名/密码 的组合情况, 而下面的例子中, 则展示了如何使用 测试模板, 在一个用例中测试所有组合情况. 当使用模板时, 所有的轮次都会被执行, 所以从功能上讲, 两者没有区别.

如上例所示, 每个组合都单独命名为一个测试用例, 很容易看出来测试目的. 不过, 如果是大量的组合情况, 也会带来统计上的混乱. 所以, 到底使用何种风格, 取决于具体的应用场景和个人喜好.

*** Test Cases ***
Invalid Password
    [Template]    Login with invalid credentials should fail
    invalid          ${VALID PASSWORD}
    ${VALID USER}    invalid
    invalid          whatever
    ${EMPTY}         ${VALID PASSWORD}
    ${VALID USER}    ${EMPTY}
    ${EMPTY}         ${EMPTY}

行为驱动型

还可以按照需求的格式来编写测试用例, 让非技术型的项目成员也能理解. 这种 可执行的需求 是所谓的 验收测试驱动开发 (Acceptance Test Driven Development, ATDD) 或 以示例表示规范 的基石.

写出这种需求/测试的一种方式是 Given-When-Then 样式, 该样式由 行为驱动开发 (Behavior Driven Development, BDD) 所普及. 当按照这种样式编写测试用例时, 初始的状态通常由 Given 起始的关键字开始, 其中的操作由 When 开头的关键字描述, 而预期结果则由 Then 开头的关键字处理. 如果某个步骤需要多个操作, 则使用 AndBut 将大家连贯起来.

*** Test Cases ***
Valid Login
    Given login page is open
    When valid username and password are inserted
    and credentials are submitted
    Then welcome page should be open

忽略 Given/When/Then/And/But 前缀

以下前缀 Given, When, Then, And and But 在搜索匹配关键字时, 如果没有全名匹配则会被忽略. 这个规则同时适用于用户关键字和库关键字. 例如, 上例中的 Given login page is open 实现为用户关键字的时候, 关键字名称带不带 Given 前缀都可以.

忽略前缀可以使得同一个关键字带上不同的前缀使用. 例如 Welcome page should be open 还可以用作 And welcome page should be open.

注解

前缀 But 在 Robot Framework 2.8.7 版本中新增支持.

关键字中嵌入数据

当编写具体的例子时, 可以在关键字的实现中传递实际的数据是很有用的. 用户关键字通过 关键字名称中嵌入参数 提供支持.