lyyyuna 的小花园

动静中之动, by

RSS

Robot Framework 新版教程 - 创建测试用例

发表于 2025-12

本节介绍测试用例的总体语法规则。关于如何通过套件文件及套件目录组织测试用例构成测试套件,将在下一文章中详细讨论。

测试用例语法

基本语法

测试用例在 test case section 中通过可用关键字构建。关键字可从测试库或资源文件导入,或在测试用例文件自身的 keyword section 中创建。

test case section 的第一列包含测试用例名称。测试用例从该列有内容的行开始,延续至下一个测试用例名称或 section 结尾。若在 section 标题与第一个测试用例之间存在内容,则视为错误。

第二列通常为关键字名称。例外情况是通过关键字返回值设置变量时,第二列(及可能的后续列)包含变量名,而关键字名位于其后。无论哪种情况,关键字名之后的列都包含该关键字的参数。

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

测试用例中的设置部分

测试用例也可以包含专属设置项。设置名称始终位于第二列(通常放置关键字的位置),其参数值则位于后续列。设置名称需用方括号标识,以区别于普通关键字。可用的设置项如下所示,本节后续将详细说明:

示例:

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

与测试用例相关的配置项

Setting section 可包含以下与测试用例相关的设置项。这些设置项主要为前文列出的测试用例专属设置提供默认值:

使用参数

之前的示例已展示了关键字如何接收不同参数,本节将更深入地探讨这一重要功能。关于如何实际实现带不同参数的用户关键字和库关键字,将在后续独立章节中详细讨论。

关键字可接收零到多个参数,部分参数可能具有默认值。关键字具体支持哪些参数取决于其实现方式,通常最佳查询渠道是查阅关键字的说明文档。

位置参数

大多数关键字都有固定数量的必须提供的参数。在关键字文档中,这通过逗号分隔的参数名称表示,例如 first, second, third。此时参数名称的实际含义并不重要(除非需要解释参数作用),但关键是要确保参数数量与文档严格一致。参数过少或过多都会触发错误。

以下测试案例使用了 OperatingSystem 库中的 Create Directory 和 Copy File 关键字。其参数分别标注为 path 与 source, 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。所有参数均可设置默认值,但注意:一旦某个参数设定了默认值,其后续的所有参数也必须具有默认值(即不能出现必选参数位于可选参数之后的情况)。

以下示例通过 Create File 关键字演示默认值的使用,该关键字参数定义为 path, content=, encoding=UTF-8。若调用时不提供任何参数或超过三个参数,则会导致错误。

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

例如,OperatingSystem 库中的 Remove Files 和 Join Paths 关键字分别具有参数 *paths 与 base、*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 中的关键字参数完全相同。

基本语法

可以通过在参数值前添加"参数名="的方式为关键字指定参数,例如 arg=value。当多个参数具有默认值时,这种方式尤其有用,因为可以仅指定部分参数名称,而让其他参数继续使用默认值。例如,某个关键字接受参数 arg1=a, arg2=b, arg3=c,若调用时只传入一个参数 arg3=override,则 arg1 和 arg2 将保持默认值,而 arg3 将获得 override 值。如果这听起来有些复杂,希望下面关于命名参数的示例能帮助理解。

命名参数语法对大小写和空格都很敏感。前者意味着如果存在参数 arg,则必须使用 arg=value 的形式,使用 Arg=value 或 ARG=value 均无效。后者意味着等号前不允许有空格,而等号后的空格将被视为给定值的一部分。

在使用命名参数语法调用用户关键字时,参数名称必须省略 ${} 修饰符。例如,具有参数 ${arg1}=first, ${arg2}=second 的用户关键字必须使用 arg2=override 的形式调用。

在命名参数后使用常规的位置参数(例如 | Keyword | arg=value | positional |)是无效的。而命名参数之间的相对顺序则无关紧要。

带变量的命名参数

在命名参数的参数名和参数值中都可以使用变量。如果参数值是单个标量变量,该变量将以原样传递给关键字。这使得在使用命名参数语法时,不仅可以使用字符串,还可以使用任何对象作为值。例如,使用 arg=${object} 的形式调用关键字时,变量 ${object} 将直接传递给关键字,而不会转换为字符串。

如果在命名参数的参数名中使用变量,变量会在与参数名匹配之前被解析。

命名参数语法要求等号必须直接写在关键字调用中。这意味着仅靠变量本身永远不会触发命名参数语法,即使其值形如 foo=bar 也不例外。这一点在将关键字封装到其他关键字中时尤其需要注意。例如,如果某个关键字接受可变数量的参数(如 @{args}),并使用相同的 @{args} 语法将所有参数传递给另一个关键字,那么调用端可能使用的 named=arg 语法将无法被识别。下面的示例说明了这种情况。

*** Test Cases ***
Example
    Run Program    shell=True    # 此处的 shell=True 不会作为命名参数传递给 Run Process

*** Keywords ***
Run Program
    [Arguments]    @{args}
    Run Process    program.py    @{args}    # 无法从 @{args} 中识别出命名参数

转义命名参数语法

仅当等号前的部分与关键字的某个参数名匹配时,才会触发命名参数语法。在某些情况下,可能存在一个值为字面量 foo=quux 的位置参数,同时另一个不相关的参数恰好名为 foo。此时,参数 foo 可能会错误地获得值 quux,或者更常见的是触发语法错误。

在这类极少出现的意外匹配场景中,可以使用反斜杠字符对语法进行转义,例如写作 foo\=quux。这样参数将直接获得字面值 foo=quux。需要注意的是,如果不存在名为 foo 的参数,则无需转义,但显式使用转义符能够使代码意图更明确,这通常是个值得提倡的做法。

命名参数的适用场景

如前所述,命名参数语法适用于关键字调用。除此之外,该语法同样适用于库导入场景。

用户关键字和大多数测试库均支持命名参数,唯一例外的是显式使用仅限位置参数的 Python 关键字。

命名参数示例

以下示例展示了如何在库关键字、用户关键字以及导入 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 支持自由命名参数(通常也称为自由关键字参数或 kwargs),其实现方式与 Python 中的 **kwargs 类似。这意味着关键字可以接收所有使用命名参数语法(name=value)且与关键字签名中定义的任何参数都不匹配的参数。

支持普通命名参数的关键字类型同样支持自由命名参数。不同关键字类型定义接收自由命名参数的方式有所不同:基于 Python 的关键字直接使用 **kwargs,而用户关键字则使用 &{kwargs}。

自由命名参数对变量的支持方式与命名参数类似。具体来说,变量既可用于参数名也可用于参数值,但转义符必须直接可见。例如,只要使用的变量存在,foo=${bar} 和 ${foo}=${bar} 都是有效的。一个额外的限制是:自由参数名必须始终为字符串类型。

示例

作为使用自由命名参数的首个示例,我们来看 Process 库中的 Run Process 关键字。其参数签名为 command, *arguments, **configuration,这意味着它接收要执行的命令(command)、可变数量的命令参数(*arguments),以及最终以自由命名参数形式传入的可选配置参数(**configuration)。以下示例同时展示了变量在自由关键字参数中的使用方式与命名参数语法完全一致。

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

更多关于在自定义测试库中使用自由命名参数语法的信息,请参阅《创建测试库》章节中的自由关键字参数(**kwargs)部分。

作为第二个示例,我们为上文中的 program.py 创建一个封装用户关键字。该封装关键字 Run Program 接收所有位置参数和命名参数,并将它们与要执行的命令名一起传递给 Run Process。

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

*** Keywords ***
Run Program
    [Arguments]    @{args}    &{config}
    Run Process    program.py    @{args}    &{config}

仅限命名参数

自 Robot Framework 3.1 起,关键字可以支持必须通过命名参数语法指定的参数。例如,若某关键字接受一个仅限命名参数 example,则调用时必须使用 example=value 的形式,直接使用 value 将无效。此语法设计灵感来源于 Python 3 中的仅限关键字参数。

在大多数情况下,仅限命名参数的工作机制与普通命名参数一致。主要区别在于:基于 Python 2 静态库 API 实现的测试库不支持此语法。

以下是通过用户关键字使用仅限命名参数的示例,这是对前文自由命名参数示例中 Run Program 关键字的改造版本,现仅支持配置 shell 参数:

*** Test Cases ***
Named-only Arguments
    Run Program    arg1    arg2              # 'shell' 取默认值 False
    Run Program    argument    shell=True    # 'shell' 设置为 True

*** Keywords ***
Run Program
    [Arguments]    @{args}    ${shell}=False
    Run Process    program.py    @{args}    shell=${shell}

关键字名称中嵌入参数

另一种完全不同的参数指定方式是将参数直接嵌入到关键字名称中。该语法同时适用于测试库关键字和用户关键字。

处理失败

当测试用例失败时

如果测试用例使用的任何关键字失败,则该测试用例被视为失败。通常,这意味着该测试用例的执行会停止,并可能执行测试清理工作,然后从下一个测试用例继续执行。如果不希望停止测试执行,也可以使用特殊的可继续运行的失败类型。

错误信息

分配给失败测试用例的错误信息直接来自失败的关键字。通常,错误信息由关键字本身生成,但某些关键字允许配置错误信息。

在某些情况下,例如使用了可继续运行的失败类型时,一个测试用例可能会失败多次。此时,最终的错误信息将通过组合各个独立错误来生成。为便于阅读报告,过长的错误信息会自动从中间部分截断,但完整的错误信息始终可以在日志文件中作为失败关键字的记录进行查看。

默认情况下,错误信息为纯文本格式,但它们也可以包含 HTML 格式。这需要通过以标记字符串 *HTML* 开头来启用。此标记将在报告和日志中显示的最终错误信息里被移除。在自定义信息中使用 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.

测试用例名称与文档

测试用例的名称直接取自测试用例部分:即测试用例列中准确输入的内容。同一测试套件中的测试用例应具有唯一的名称。与此相关的是,您还可以在测试内部使用自动变量 ${TEST_NAME} 来引用测试名称。该变量在测试执行期间(包括所有用户关键字、测试初始化及测试清理)均可用。

从 Robot Framework 3.2 开始,测试用例名称中可能存在的变量会被解析,从而使最终名称包含变量的值。如果变量不存在,其名称将保持不变。


*** Variables ***
${MAX AMOUNT}      ${5000000}

*** Test Cases ***
Amount cannot be larger than ${MAX AMOUNT}
    # ...

[Documentation] 设置项允许为测试用例设置自由格式的文档。该文本将显示在命令行输出以及生成的日志和报告中。如果文档内容较长,可以拆分为多行。可以使用简单的 HTML 格式化,并且可以通过变量使文档内容动态变化。可能存在的不存在的变量将保持不变。

*** Test Cases ***
Simple
    [Documentation]    Simple and short documentation.
    No Operation

Multiple lines
    [Documentation]    First row of the documentation.
    ...
    ...                Documentation continues here. These rows form
    ...                a paragraph when shown in HTML outputs.
    No Operation

Formatting
    [Documentation]
    ...    This list has:
    ...    - *bold*
    ...    - _italics_
    ...    - link: http://robotframework.org
    No Operation

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

为测试用例设定清晰且具有描述性的名称至关重要,通常情况下,这样做就不再需要额外的文档。如果测试用例的逻辑需要文档说明,这通常意味着测试用例中的关键字需要更好的命名或进行增强,而不是添加额外的文档。最后,像上述最后一个示例中的环境和用户信息这类元数据,通常更适合使用标签来指定。

为测试用例添加标签

在 Robot Framework 中使用标签是一种简单而强大的机制,用于对测试用例及用户关键字进行分类。标签为自由文本,除了下面讨论的保留标签外,Robot Framework 本身对它们没有特殊含义。标签至少可用于以下目的:

为测试用例指定标签有多种方式,如下所述:

例子:

*** Settings ***
Test Tags       requirement: 42    smoke

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

*** Test Cases ***
No own tags
    [Documentation]    Test has tags 'requirement: 42' and 'smoke'.
    No Operation

Own tags
    [Documentation]    Test has tags 'requirement: 42', 'smoke' and 'not ready'.
    [Tags]    not ready
    No Operation

Own tags with variable
    [Documentation]    Test has tags 'requirement: 42', 'smoke' and 'host: 10.0.1.42'.
    [Tags]    host: ${HOST}
    No Operation

Remove common tag
    [Documentation]    Test has only tag 'requirement: 42'.
    [Tags]    -smoke
    No Operation

Remove common tag using a pattern
    [Documentation]    Test has only tag 'smoke'.
    [Tags]    -requirement: *
    No Operation

Set Tags and Remove Tags keywords
    [Documentation]    This test has tags 'smoke', 'example' and 'another'.
    Set Tags    example    another
    Remove Tags    requirement: *

如示例所示,标签可以通过变量创建,但在其他情况下,它们会保留在数据中使用的确切名称。当标签进行比较时(例如,用于收集统计数据、选择要执行的测试或去除重复项),比较操作对大小写、空格和下划线不敏感。

如上文示例所示,使用 -tag 语法移除标签支持简单的模式,例如 -requirement:*。以连字符开头的标签,除非在 [Tags] 设置中使用,否则没有特殊含义。如果需要使用 [Tags] 设置一个以连字符开头的标签,可以使用转义格式,如 \-tag。

目前,-tag 语法仅可用于通过 [Tags] 设置项来移除标签,但计划在 Robot Framework 8.0 中,在 Test Tags 设置中也支持此功能(#5250)。在 Robot Framework 7.2 中,已弃用 Test Tags 设置中值为以连字符开头的字面量的标签(#5252)。如果需要此类值的标签,可以使用 \-tag 这样的转义格式。

弃用 Force Tags 和 Default Tags

在 Robot Framework 6.0 之前,可以通过 Setting 节中的两种不同设置来为测试指定标签:

这两种设置目前仍然有效,但已被视为弃用。未来(很可能在 Robot Framework 8.0 中)会添加可见的弃用警告,并最终移除这些设置。可以使用 Tidy 等工具来简化迁移过程。

更新 Force Tags 仅需将其重命名为 Test Tags。Default Tags 设置将被完全移除,但 Robot Framework 7.0 引入的 -tag 功能提供了相同的底层功能。以下示例展示了所需的更改。

旧语法:

*** Settings ***
Force Tags      all
Default Tags    default

*** Test Cases ***
Common only
    [Documentation]    Test has tags 'all' and 'default'.
    No Operation

No default
    [Documentation]    Test has only tag 'all'.
    [Tags]
    No Operation

Own and no default
    [Documentation]    Test has tags 'all' and 'own'.
    [Tags]    own
    No Operation

新语法:

*** Settings ***
Test Tags      all    default

*** Test Cases ***
Common only
    [Documentation]    Test has tags 'all' and 'default'.
    No Operation

No default
    [Documentation]    Test has only tag 'all'.
    [Tags]    -default
    No Operation

Own and no default
    [Documentation]    Test has tags 'all' and 'own'.
    [Tags]    own    -default
    No Operation

保留标签

用户通常可以自由使用在其上下文中有效的任何标签。然而,存在某些标签对 Robot Framework 本身具有预定义的含义,将它们用于其他目的可能会导致意外结果。Robot Framework 目前及将来拥有的所有特殊标签都带有 robot: 前缀。因此,为避免出现问题,用户除非确实需要激活特定功能,否则不应使用任何带有此前缀的标签。当前的保留标签列表如下,但未来可能会添加更多此类标签。

自 RobotFramework 4.1 起,保留标签默认在标签统计中被隐藏。当通过 --tagstatinclude robot:* 命令行选项明确包含时,它们才会显示。

测试初始化与清理

Robot Framework 具备与其他许多自动化测试框架类似的测试初始化与清理功能。简而言之,测试初始化是在测试用例执行前运行的操作,而测试清理则在测试用例执行后运行。在 Robot Framework 中,初始化与清理操作本身也只是普通的关键字,可以附带参数。

一次初始化或清理始终对应一个关键字。如果需要处理多个独立任务,可以为此创建更高级别的用户关键字。另一种解决方案是使用 BuiltIn 库中的 Run Keywords 关键字来执行多个关键字。

测试清理在两个方面具有特殊性。首先,即使测试用例失败,清理也会执行,因此可用于执行那些无论测试用例状态如何都必须完成的清理活动。其次,即使清理中的某个关键字失败,其后的所有关键字仍会继续执行。这种"失败后继续运行"功能也可用于普通关键字,但在清理操作中默认启用。

在测试用例文件中为测试用例指定初始化或清理的最简单方式,是在 Setting 节中使用 Test Setup 和 Test Teardown 设置项。单个测试用例也可以拥有自己的初始化或清理,它们通过测试用例节中的 [Setup] 或 [Teardown] 设置项定义,并会覆盖可能的 Test Setup 和 Test Teardown 设置。在 [Setup] 或 [Teardown] 设置项后不指定关键字,意味着没有初始化或清理操作。也可以使用值 NONE 来表示测试没有初始化/清理。

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

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

Overridden setup
    [Documentation]    Own setup, teardown from setting section
    [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}

作为初始化或清理操作来执行的关键字名称可以是一个变量。这样便于通过从命令行以变量形式提供关键字名称,从而在不同环境中使用不同的初始化或清理例程。

测试模板

测试模板能够将常规的关键字驱动型测试用例转化为数据驱动型测试。普通的基于关键字的测试用例,其主体由关键字及其可能的参数构成;而使用模板的测试用例,仅包含模板关键字的参数。我们无需在每个测试中重复使用同一个关键字,也无需在文件的所有测试中重复使用,而可以实现每个测试只用一次,甚至整个文件仅使用一次。

模板关键字既可以接收常规的位置参数和命名参数,也支持将参数内嵌于关键字名称中。与其他设置不同,无法使用变量来定义模板。

基本用法

下面的示例测试用例展示了如何将一个接受常规位置参数的关键字用作模板。这两个测试在功能上完全一致。

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

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

如示例所示,可以使用 [Template] 设置来为单个测试用例指定模板。另一种方法是在 Settings 节中使用 Test Template 设置,这样该模板将应用于该测试用例文件中的所有测试。[Template] 设置会覆盖 Settings 节中可能设置的模板,并且将 [Template] 的值设为空则表示该测试没有模板,即使使用了 Test 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

模板化测试的特殊之处在于,即使其中一个或多个迭代失败或跳过,所有迭代仍会执行。具有多次迭代的模板化测试的汇总结果如下:

使用嵌入式参数的模板

模板支持一种嵌入式参数的变体语法。在模板中,该语法的工作原理是:如果模板关键字的名称中包含变量,这些变量会被视为参数的占位符,并被替换为模板所使用的实际参数。然后,生成的关键字将被直接调用,而不再附带位置参数。这通过一个示例能最清晰地说明:

*** 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 循环结合使用,则该模板将应用于循环内的所有步骤。在这种情况下,同样会启用“失败后继续”的模式,这意味着即使存在失败,所有步骤仍会对所有循环元素执行。

*** Test Cases ***
Template with FOR loop
    [Template]    Example keyword
    FOR    ${item}    IN    @{ITEMS}
        ${item}    2nd arg
    END
    FOR    ${index}    IN RANGE    42
        1st arg    ${index}
    END

结合 IF/ELSE 结构的模板

IF/ELSE 结构也可以与模板结合使用。这很有用,例如,当与 FOR 循环一起使用时,可以过滤要执行的参数。

*** Test Cases ***
Template with FOR and IF
    [Template]    Example keyword
    FOR    ${item}    IN    @{ITEMS}
        IF  ${item} < 5
            ${item}    2nd arg
        END
    END

不同的测试用例风格

编写测试用例有几种不同的方式。描述某种工作流的测试用例可以采用关键字驱动或行为驱动风格来编写。数据驱动风格则可用于使用不同的输入数据来测试相同的工作流程。

关键字驱动风格

工作流测试(例如前面描述的 Valid Login 测试)由多个关键字及其可能的参数构成。其典型结构是:首先将系统置于初始状态(Valid Login 示例中的 Open Login Page),然后对系统执行某些操作(Input Name、Input Password、Submit Credentials),最后验证系统是否按预期响应(Welcome Page Should Be Open)。

数据驱动风格

编写测试用例的另一种方式是数据驱动方法。在这种风格中,测试用例只使用一个更高级别的关键字(通常创建为用户关键字)来隐藏实际测试流程。当需要使用不同的输入和/或输出数据测试同一场景时,这类测试非常有用。尽管可以在每个测试中重复使用相同的关键字,但测试模板功能允许只指定一次要使用的关键字。

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

上面的示例包含了六个独立的测试,分别对应每种无效的用户名/密码组合。而下面的示例则展示了如何将所有组合整合在一个测试中。使用测试模板时,即使测试过程中出现失败,测试内的所有轮次仍会执行,因此这两种风格在功能上并没有本质区别。在上面的示例中,每个组合都有独立的命名,这使测试内容更加清晰易读;但如果有大量此类测试,可能会影响统计结果的整洁度。具体采用哪种风格取决于具体情境和个人偏好。

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

行为驱动风格

测试用例也可以编写成非技术性项目相关人员也需理解的需求形式。这类可执行的需求通常被称为验收测试驱动开发(ATDD)或实例化规格,是这一开发流程的基石。

编写这些需求/测试的一种方式是采用行为驱动开发(BDD)所推广的 Given-When-Then 风格。以此风格编写测试用例时,初始状态通常使用以 Given 开头的关键字描述,操作使用以 When 开头的关键字描述,预期结果则使用以 Then 开头的关键字描述。如果一个步骤包含多个动作,还可以使用以 And 或 But 开头的关键字。

*** 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 和 But 这些前缀。例如,上面例子中的 Given login page is open 通常在实现时会省略单词 Given,使其名称仅为 Login page is open。省略前缀使得同一个关键字可以与不同的前缀一起使用。例如,Welcome page should be open 可以同时用作 Then welcome page should be open 或 And welcome page should be open。

将数据嵌入到关键字中

在编写具体示例时,能够将实际数据传递给关键字实现非常有用。这可以通过将参数嵌入到关键字名称中来实现。

lyyyuna 沪ICP备2025110782号-1