测试用例语法
基本语法
测试用例基于已有关键字构建,以测试用例表为单位组织。关键字可以从资源文件和测试库中导入,也可以在关键字表中编写自己的关键字。
测试用例表的第一列是用例的名字,这是一个测试用例的开始,每个用例都是如此,直到表的末尾。在表头和第一个测试之间不应该有其他的内容。
通常表的第二列会有关键字,也有可能是定义的变量(用来接收关键字的返回值)。接下来的几列有可能用于填放关键字的参数。
请看下面的例子:
*** 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 |
测试用例表中的设置项
测试用例可以有自己的设置。设置名称永远在第二列第二行开始,关键字位于设置项之后。设置的名称左右有中括号,用于和关键字区分。以下是所有可能的设置项:
●[Documentation] 描述一个测试用例的文档。
●[Tags] 指定该测试用例的标签。
●[Setup], [Teardown] 指定测试用例的Setup 和 Teardown。
●[Template] 指定某个关键字作为模板,可将测试用例转换为数据驱动型的测试。
●[Timeout] 指定测试用例执行的超时时间。
例子:
*** Test Cases *** Test With Settings [Documentation] Another dummy test [Tags] dummy owner-johndoe Log Hello, world! |
设置表中设置项
测试用例相关的设置也可以放在设置表中。如果测试用例表没有的话,这些设置将作为测试用例的默认设置。
●Force Tags, Default Tags 作为默认标签。
●Test Setup, Test Teardown 作为测试用例的默认 Setup 和 Teardown。
●Test Template 作为默认的模板。
●Test Timeout 作为默认的超时时间。
使用参数
之前的例子展示了关键字可以传入参数,这一节将详述参数的功能。
关键字可以有零到多个参数,参数也可以有默认值。关键字接受什么参数取决于实现,最好的办法是查阅关键字的文档。
强制性参数
大部分关键字会有一些必填的参数。自己开发关键字时,对参数名叫什么没有强制要求,建议使用有意义的英文名。参数个数一定要和文档中国匹配,过多或过少都会导致错误。
下面的用例使用了 OperatingSystem 库中的 Create Directory 和 Copy File 关键字。参数分别为 path 和 soure,destination,这意味着分别需要一个和两个参数。最后一个是内置的 No Operation 关键字,它不需要参数。
*** Test Cases *** Example Create Directory ${TEMPDIR}/stuff Copy File ${CURDIR}/file.txt ${TEMPDIR}/stuff No Operation |
默认值
有默认值的参数不是必填项。在文档中,这些参数有一个等于号 name=default value。所有参数都可以有默认值,但这类参数应位于普通参数之后。
下面这个 Create File 关键字有 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 关键字分别有参数 *path 和 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 将使用默认值,最后个参数被 override 值覆盖。虽然听起来有点复杂,看下面这个例子就能明白。
*** 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} |
有名参数语法对大小写和空格敏感。前者意味着,如果你有一个参数 arg,那么你必须使用 arg=value 调用,Arg=value 或者是 ARG=value 都不起作用。后者意味着,等号前后都不能有空格。
位置型参数不能在有名参数之后使用。从 Robot Framework 2.8 之后,这会强制报错,有名参数之间的相对顺序则没有硬性要求。
带变量的有名参数
在参数名和值上都可以使用参数。如果值是单一的标量,那会直接传给关键字。不只是字符串,任何对象,都可以作为值直接传给有名参数。例如,用 arg=${object} 的方式,会把变量 ${object} 的值原原本本地传给关键字,而不是转换成字符串后传给关键字。
有名参数语法的特点是要求调用关键字时有等于号。这意味着只有变量是不会触发有名参数语法的,即使该变量的值是 foo=var。在变量嵌套调用的时候要挺特别注意这点,例如下面这个例子
*** Test Cases *** Example Run Program shell=True # 在 Run Process 关键字中这不是一个有名参数 *** Keywords *** Run Program [Arguments] @{args} Run Process program.py @{args} # 没有解析出有名参数 |
让关键字支持自由变量需要下节的技术。
关键字中的自由参数
从 Robot Framework 2.8 开始,Python 的 (**kwargs) 可变参数类型。听起来和之前的任意个参数类似,这里不仅是任意多个参数,而且使用有名参数的语法。
Kwargs 例子
让我们用 Process 库中的 Run Process 关键字作为第一个例子。它的参数为 command, *arguments, **configuration
*** Test Cases *** Using Kwargs Run Process program.py arg1 arg2 cwd=/home/user # cwd=/home/user 传给 kwargs Run Process program.py argument shell=True env=${ENVIRON} # shell=True env=${ENVIRON} 传给 kwargs |
在创建测试库章节中会详述 kwargs 语法。
运行失败
当测试用例失败时
当一个关键字失败时,所在的测试用例将停止运行,执行 test teardown 部分,然后继续运行下一个测试用例。你也可以用特殊语法(之后章节会详述)忽略失败的关键字。
错误消息
测试用例运行失败的错误消息直接来自于失败的关键字。这些错误消息可由关键字自行配置。
有些情况下,一个测试用例可能会失败多次,那么错误消息会被合并成单一的错误。在测试报告中,过长的错误消息会被截断,需要到日志文件中才能查看完整的错误消息。
默认情况下错误消息是纯文本,从 Robot Framework 2.8 开始,可以用 *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} 来引用测试用例名,在 test setup 和 test teardown 阶段都可以引用该变量。
对于程序员来讲,文档的意义不言而喻。配置项 [Documentation] 可以设置一个测试用例的文档。在命令行,测试结果日志和报告上都可以看到该文档。文档支持 HTML 格式,也可以使用变量。
下面是例子:
*** 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 中标签非常简单,这是一个对测试用例分类的好方法。标签常用在以下方面:
●标签在测试报告、日志作为元数据。
●基于标签对测试用例进行总数、通过率和失败率作数据统计。
●基于标签选择特定测试用例执行。
●基于标签标记关键测试用例。
那如何使用呢?通常,会:
●设置表中的强制标签。一个文件中所有测试用例都会得到该标签。如果用于测试集的启动文件中,那该测试集的所有测试用例都会拥有该标签。
●设置表中的默认标签。一个测试用例如果没有 [Tags] 设置,就会得到默认标签。默认标签不支持测试集启动文件。
●测试用例表中的 [Tags]。只要设置,测试用例就会得到标签。可以覆盖默认标签的值,甚至可以用空值 NONE 来覆盖。
●–settag 命令行。用命令行 robot 启动时添加该项,可以为每个测试用例添加标签。
●Set Tags, Remove Tags, Fail 和 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: 不要在实际项目中使用,它们被框架自身使用。
Test setup 和 teardown
大部分框架都有 test setup 和 test teardown 功能,Robot Framework 也不例外。简言之,test setup 保证在测试用例执行前一定会执行,而 test teardown 保证测试用例执行完之后(即使运行失败)一定会执行。
在 Robot Framework 这两者都是由普通的关键字构成的,且各自是一个单一的关键字。所以通常需要用户自己在多个关键字之上抽象出高级关键字。
从测试理论上来说,test setup 用于初始化测试环境,test teardown 用于清理测试环境(因为即使测试用例失败,也会执行 teardown,保证环境在执行完之后能 100% 恢复如初)。
在设置表中可以用 Test Setup 和 Test Teardown 设置项设置默认值,也可以在每个测试用例开头用 [Setup] 和 [Teardown] 覆盖默认值,用控制 NONE 覆盖也是可以的,表示该用例不需要 test setup 和 test 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} |
例子中的最后一个,设置项中支持变量。可以在不修改源码的情况下,借助该特性为不同的测试环境设置不同的 test setup 和 test teardown。
测试模板
模板可以将关键字驱动的测试用例转换成数据驱动的测试用例。对于一类相同的测试,不再需要重复书写关键字。
模板关键字可以接受普通位置型参数和有名参数。在设置项中,和其他配置不同,模板不接受变量。
基本用法
模板关键字就是普通的关键字,例如下面两个用例是完全等价的:
*** Test Cases ** Normal test case Example keyword first argument second argument Templated test case [Template] Example keyword first argument second argument |
在文件开头的设置表 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
也可以在设置项中显式指定部分参数的值:
Test Cases
Only some arguments
[Template] The result of ${calculation} should be 3
1 + 2
4 - 1
甚至可以将关键字的一部分变成参数:
Test Cases
New arguments
[Template] The ${meaning} of ${life} should be 42
result 21 * 2
循环中使用模板
如果和循环语句一起使用模板,那么模板仅仅是作用于循环之内的关键字。循环之内如果有数据运行失败,循环不会停止,而是跳过失败的这一轮。
*** Test Cases *** Template and for [Template] Example keyword :FOR ${item} IN @{ITEMS} \ ${item} 2nd arg :FOR ${index} IN RANGE 42 \ 1st arg ${index} |
不同测试用例的风格
关键字驱动
这是 Robot Framework 的最重要特征。一个测试用例,通常分为三个步骤:环境初始化,对系统操作,验证系统输出。每一个步骤抽象成一个关键字,测试也就完成了。
数据驱动
有些测试场景,仅仅是输入数据不同,步骤却是重复的,如果每个测试场景写一个测试用例,那会用例数量会快速膨胀,既难以阅读又不方便修改(牵一发动全身)。
比如为了测试登陆功能,我们会尝试各种用户名密码组合:
*** 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} |
测试用例一目了然,生成的测试报告也简洁易懂。
行为驱动
最后执行验收测试的,常常是一些不懂技术的人员。上面的关键字驱动和数据驱动对于他们来说都是天书,这时候行为驱动的测试更流行。行为驱动分为三个步骤: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 前缀
Robot Framework 语法器会忽略这些 Given/When/Then/And/But 前缀,直接去寻找 login page is open 等关键字。也就是说 Given login page is open 等价于 login page is open。
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。