RobotFramework(一)

文章目录

  • 简介
  • 安装
  • 基础语法
    • 测试数据(Test Data)
      • 解析规则
    • 测试用例
      • 参数
      • 失败处理
      • 名称和文档
      • 标签
      • Setup&Teardown
      • 测试模板
      • 类型
    • 测试套件
      • 自定义
    • 测试库
      • 标准库
    • 变量
      • 标量
      • 列表
      • 字典
      • 环境变量
      • 创建
      • 关键字创建
      • 其他
      • 高级特性
    • 用户关键字
      • 语法
      • Teardown
    • 高级特性
  • 小结

简介

  • 这是一个基于python的测试框架
    • 支持web自动化,接口自动化,APP自动化测试
  • 使用关键字驱动,就是说可以用python封装出关键字
  • 使用关键字构建可被执行的测试用例

    Robot Framework is a generic open source automation framework for acceptance testing, acceptance test driven development (ATDD), and robotic process automation (RPA). It has simple plain text syntax and it can be extended easily with libraries implemented using Python or Java.

安装

  • 可以参考官方的说明
    • 中文手册(版本比较旧)
    • 对应的是官方的User Guide
  • 这里使用源码在Ubuntu上安装
    • Download files里复制链接下载,wget下来
    • 使用.whl配合pip install,或者.zip解压再unzip后,python setup.py install都可以
    • Windows环境下可以参考教程
  • 检查版本:robot --version
    • Robot Framework 4.1.1 (Python 3.5.2 on linux)
  • 在n174-h183机器上安装
    • 使用 pip3 install robotframework 安装
    • robot --version Robot Framework 4.1.2 (Python 3.6.8 on linux)

基础语法

  • 了解一下概念
    • 测试用例:由测试用例文件所创建,即test case
    • 测试套件:一个测试用例会自动创建测试套件
    • 测试套件文件夹:包含多个测试用例的文件夹,会形成一个高层级的test suite directory
      • 多个测试套件文件夹形成的文件夹又形成一个更高层级的目录
    • 测试库:包含最底层的关键字
    • 资源文件:包含高层次的用户关键字和变量
    • 变量文件:提供创建变量的方式

测试数据(Test Data)

  • 这里的Data就是我们自定义的robot语法的文件,后面统一称为测试用例或测试用例文件
    • case是由这些文件生成的
  • 都以section的格式定义
  • 支持tab分隔的TSV格式,纯文本格式,reStructuredText (reST)格式
    • 目前已经完全不支持HTML格式
    • 目前最常用的还是纯文本的空格分隔格式(Space separated format)和管道符(|)分隔格式
  • 可以通过后缀判断怎么解析文件:.tsv .txt .robot .rst .rest
    • 但测试用例一般用.robot
    • 资源文件一般用.resource
  • 不同格式都有测试用例的模板
  • 测试数据按结构划分为4部分
    RobotFramework(一)_第1张图片
  • 每个section都需要header标识,例如*** Settings ***
  • 每个section的作用自行翻译吧
  • 执行文件时,首先将数据拆分为行,然后将行拆分为关键字和参数等标记,看个例子吧:
    *** 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} |
    
    • 使用空格分隔方式,关键字和参数之间使用两个或多个空格(推荐四个及以上),或者一个或多个Tab
    • reStructuredText文件是将code嵌入在robot文件中,可以使用code指令标记,这样的文件以.rst .rest结尾
    # 当执行一个包含 reStucturedText 文件的目录时,必须使用 --extension 选项来明确告诉这些文件应该被解析
    .. code:: python
    
       # This code block is ignored.
       def example():
           print('Hello, world!')
    

解析规则

  • Ignore:在解析robot文件时,会忽略以下内容
    • 评论(注释)
    • 空行,使用管道分隔的空单元格
    • #后的数据,类似python注释
  • Escape character(转义字符)
    • 一般使用\转义
    • 转义了特殊字符,就可以使用他们的字面值
      RobotFramework(一)_第2张图片
    • 有些使用\转移后,失去了字面值,我们也称之为转义序列
      RobotFramework(一)_第3张图片
    • 如果要转换成字节可以使用内置库中的函数
  • 转义空值
    • 当使用空值时必须将转义,否则可能会被忽略,下面是两个例子
      *** Test Cases ***
      Using backslash(反斜线)
          Do Something    first arg    \
          Do Something    \            second arg
      
      Using ${EMPTY}
          Do Something    first arg    ${EMPTY}
          Do Something    ${EMPTY}     second arg
      
    • 可以使用\或者${EMPTY}表示(相当于占位符)
    • 类似的,可以使用${SPACE}使空格不被忽略
  • 换行但继续
    • 又有时一行代码太长,需要换行继续写,可以使用...
      *** Settings ***
      Documentation      Here we have documentation for this suite.
      ...                Documentation is often quite long.
      ...
      ...                It can also contain multiple paragraphs.
      Default Tags       default tag 1    default tag 2    default tag 3
      ...                default tag 4    default tag 5
      
      *** Variable ***
      ${STRING}          This is a long string.
      ...                It has multiple sentences.
      ...                It does not have newlines.
      

测试用例

  • 测试用例(Test Case)是在测试用例文件的*** Test Cases ***部分定义的
  • 使用关键字构造,关键字可以从 使用测试库资源文件导入,也可以使用在当前测试用例文件中的 关键字
  • 看个例子吧
    *** 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!
    # [Tags]	用于指定 测试用例的标签.
    # [Setup], [Teardown]	用于指定 Setup和Teardown.
    # [Template]	用于指定 测试模板. 测试用例本身将只包含数据, 每行数据都是传递给该关键字的参数, 最终实现数据驱动的测试.
    # [Timeout]		用于设置 test case timeout. timeouts 将在独立的章节讨论
    

参数

  • 关键字可以理解成函数,所以能带一个或多个参数
  • 必填参数(Positional arguments),也叫位置参数,因为实参的传递严格按照形参的位置给
    # syntax 语法
    *** Test Cases ***
    Example
        Create Directory    ${TEMPDIR}/stuff
        Copy File    ${CURDIR}/file.txt    ${TEMPDIR}/stuff
        No Operation
    # Create Directory Copy File 都是OperatingSystem library中定义好的关键字
    
  • 缺省参数(Default values),带默认值的参数
    # 这些东西和其他语言一样,带默认值的参数必须放在后面
    *** 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
        
    # Create File 关键字的参数就是 path, content=, encoding=UTF-8. 所以可以只传一个path,content= 表示内容为空
    
  • 可变数量的参数(Variable number of arguments),通过在参数名称前加一个星号 * 来表示
    *** 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
    # Remove Files 和 Join Paths, 参数分别是 *paths 和 base, *parts. 
    # 类似于python中的*args ,使用元组接收
    # 和位置参数/缺省参数一起使用时,必须放在最后,这部分参数就没有名字了
    
  • 命名参数(Named arguments)
    • 定义时给默认值的叫缺省参数
    • 调用时指定参数名字的,叫命名参数,更灵活
    • 这里有个问题,关键字中调用另一个关键字,Run Program 把所有的参数都通过@{args}传递,可能其中包含的命名参数shell=True不会被识别
    *** 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形式,和Python一样!这里叫任意命名参数(free named argument)
    • 因为可变数量参数*args是没有名字的,相当于不限数量的位置参数
    • 当前最新的版本中, 所有的关键字都可以使用 **kwargs,Java测试库也支持
    *** Test Cases ***
    Using Kwargs
        Run Process    program.py    arg1    arg2    cwd=/home/user
        Run Process    program.py    argument    shell=True    env=${ENVIRON}
    # 当然,如果不看定义关键字的语法,arg1  arg2 可能是位置参数,可能是缺省参数,也可能是可变数量参数;cwd=/home/user
    # 可能是缺省参数,也可能是任意命名参数
    

失败处理

  • 一个测试用例中用到的任何一个关键字发生失败, 则该用例也执行失败
  • 但是可以使用 Test Teardown 模式和特殊的continuable failures让测试继续执行
    • 后面会有详细介绍,Teardown后有关键字失败但仍可继续其他关键字
  • 错误信息
    • 测试用例的错误信息直接来源于失败的关键字
    • 有的关键字允许用户配置错误信息
    • 完整的信息总是可以在 log 文件中找到;因为report中会截断过长的信息
    • 可以使用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 MAGIC number.
    

名称和文档

  • 测试用例的名称在一个 test suite 中是唯一的
    • 或者说,一个test case的name代表测试的一个最小单位,里面可以包含多个关键字(步骤)
  • 可以通过变量 ${TEST_NAME} 指定,这个变量在测试执行的任何阶段都可以访问到
  • 哦忘了说,*** Test Cases ***下第一行顶头的就是用例名,可以使用变量
    *** Variables ***
    ${MAX AMOUNT}      ${5000000}
    
    *** Test Cases ***
    Amount cannot be larger than ${MAX AMOUNT}	# 如果这个变量不存在,那就只有左侧的部分
        # ...
    
  • 文档 [Documentation] 用来为用例设置一段文档说明. 这个说明会显示在命令行的输出中, 以及后续的测试日志和测试报告中
  • 文档中可以使用HTML格式和变量
    *** Test Cases ***
    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
    
  • 测试用例有一个清楚的, 描述性的名称就可以不需要文档了
  • 如果涉及元数据(environment & user information)等,可以使用打标签的方式

标签

  • 标签的作用
    • 标签在 reports, logs 以及测试数据中展示, 提供关于测试用例的元数据信息
    • 用例的 统计 (total, passed, failed 就是自动基于标签收集的)
    • 使用标签, 可以 包含或排除 测试用例(这个有点小复杂)
    • 使用标签, 可以指定哪些用例可以跳过
  • Settings这个section中可以定义不同类型的Tag
    • Force Tags,所有用例都被指定打上这些标签
    • Default Tags,没有单独设置 [Tags] 的用例将被打上这些默认标签(半强制)
    • [Tags],在Test Casessection中使用,可以设置一个空值(NONE)来覆盖默认标签
    • --settag,可以通过命令行执行,给所有case加上tag
    • Set Tags, Remove Tags内置关键字动态操纵tag
    • 标签可以使用变量创建(如果变量存在)
    *** 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]		# 覆盖默认tag
        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-前缀开头
    • 例如robot-exit表示优雅的结束测试
  • 4.1版本开始,统计信息默认不显示,可以通过在启动测试命令行中添加--tagstatinclude 'robot:* 显示

Setup&Teardown

  • 简而言之, setup在测试用例之前执行, 而teardown在测试用例之后执行
    • 类似CSS的伪类选择器
  • 都是带参数的关键字,并且各自只能指定一个关键字.
  • 如果涉及到多个步骤, 只能创造一个更高层的用户关键字(user keywords)
    • 也可以使用 BuiltIn 中关键字 Run Keywords 来执行多个关键字
  • Teardown is special in two ways
    • 在用例失败时也会被执行,常用来做测试环境的清理工作
    • 所有的关键字都会被执行, 哪怕其中有的执行失败;之前在失败处理部分也介绍过(失败仍继续)
      • 普通的关键字也能有失败后继续的模式,但是默认关闭
  • 使用方法
    • 在Settings中
    *** Settings ***
    Test Setup       Open Application    App A
    Test Teardown    Close Application		# 给每个case都加上S&T
    
    • 每个单独的用例也可以指定自身的Setup或Teardown
    *** 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]	# 覆盖Settings section中的设置
    
    • Setup或Teardown中指定的关键字名称可以使用变量传递
    • S&T针对最小测试单位,即每个test case name中都有

测试模板

  • 测试模板将普通的 keyword-driven 测试转为 data-driven 测试
  • 很简单,在[Template]中指定关键字,后续写参数就可以,也可在Settings中全局设置
  • 针对重复使用同一关键字时
    *** Test Cases **
    Normal test case
        Example keyword    first argument    second argument
    
    Templated test case
        [Template]    Example keyword
        first argument    second argument
    
    *** 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		# 默认失败后继续,第一轮失败了,second round继续
    
    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
    
    Template and for		# 带for循环的模板
        [Template]    Example keyword
        :FOR    ${item}    IN    @{ITEMS}
        \    ${item}    2nd arg
        :FOR    ${index}    IN RANGE    42
        \    1st arg    ${index}
    

类型

  • 测试用例大概分为关键字驱动型、数据驱动型和行为驱动型
  • 关键字驱动型,也叫流程驱动型
    • 即本文“测试用例”一开始的那个例子
    • 系统进入某个初始状态
    • 然后对系统执行一些操作
    • 最后校验是否符合某个预期
  • 数据驱动型
    • 仅使用一个高级别关键字(一般是user keywords)
    • 针对某个相同的测试场景反复多次测试时;例如测试对非法信息登陆的检测功能
    *** 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}
    
    • 当然,也可以换一种模式,例如针对invalid password进行混合测试,具体怎么使用看场景和个人喜好
    *** 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)
    • 一般按照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 login page is open 实现为用户关键字的时候,关键字名称带不带 Given 前缀都可以
    • 忽略前缀可以使得同一个关键字带上不同的前缀使用;个人感觉在自定义关键字时还是避免使用这些关键字

测试套件

  • 上面一小节了解了测试用例文件,它会自动创建了一个测试套件, 包含其中所有的测试用例
    • 从robot、test data/test case file到test case的关系,他们的关系可以理解成python -> .py -> def
    • 形式上,一个py文件中包含多个测试函数(别超过十个),函数名即这里的每个case名称
  • 这节了解测试套件(test suite
    • 一般,一个测试用例文件形成一个测试套件,也可以多个测试用例组织形成一个套件
    • 套件和测试文件可以是一对一和一对多的关系,套件中的一些设置更便于测试执行和管理
    • 最终测试的流程还是得test case file定义,最终的执行交给suite
  • 从3.1版本之后新增了创建任务task的功能,和创建测试文件一样,也能生成套件(task suite)

自定义

  • 自定义测试套件(customize test suite),直接在测试用例文件Setting section中
    • Documentation
    • Metadata
    • Suite Setup, Suite Teardown
    • 都可以加冒号
  • 测试套件文件夹
    • 测试用例文件可以组织在文件夹中,形成更高级的测试套件(目录套件)
    • 生成的目录套件夹不能直接包含case,但是可以包含其他套件(这些套件中包含case)
    • 当一个测试目录被执行, 其中的文件和子目录会按如下规则递归处理:
      • 以点 . 或下划线 _ 开头的文件/目录名——忽略
      • 目录 CVS (注意大小写)——忽略
      • 文件的扩展名不在 可识别扩展名 之列的(.tsv, .txt, .rst, 或 .rest) ——忽略
      • 其它文件和目录被忽略
      • 如果被处理的文件或者目录下不包含任何用例,则也会忽略
    • 非法文件警告
      • 一般情况下,不包含合法测试用例表格的文件会被忽略掉,但同时把消息写入系统日志
      • 可以在命令行中指定选项 --warnonskippedfiles, 这样就将该消息作为警告处理,警告消息最终出现在 测试执行错误区
    • OK,以后测试套件就分别称为测试套件(test case file直接生成)和目录套件(test case files directory 生成)
  • 初始化
    • 目录创建的测试套件和文件创建的套件一样有类似的设置,但需要在初始化文件中整
    • 文件名:__init__.ext,借鉴自python
    • 初始化文件中除了不能包含测试用例表格(test case),以及不支持某些设置项,其它一样
    • 初始化文件中创建或者导入的变量和关键字在下层的测试套件中 不可用,主要是设置一些东西
    • 想要共享变量和(或)关键字, 可以放在资源文件,再由测试用例文件导入
    • 设置方法:
      Documentation, Metadata, Suite Setup, Suite Teardown
      	这些测试套件相关的设置和测试用例文件中的设置一样.
      Force Tags
      	为下面的所有用例指定标签.
      Test Setup, Test Teardown, Test Timeout
      	为下面的测试用例设置默认的 setup/teardown 或 超时动作. 测试用例可以单独设置以覆盖这里的配置.
      Default Tags, Test Template
      	不支持
      
    • 来个例子吧:
      *** Settings ***
      Documentation    Example suite
      Suite Setup      Do Something    ${MESSAGE}
      Force Tags       example
      Library          SomeLibrary
      
      *** Variables ***
      ${MESSAGE}       Hello, world!
      
      *** Keywords ***
      Do Something
          [Arguments]    ${args}
          Some Keyword    ${arg}
          Another Keyword
      
  • 名称和文档
    • 测试套件的名称由文件或目录名称构造,首字母大写并使用空格代替下划线
      • 例如测试目录是my_test_directory,生成的套件名称就是:My Test Directory
    • 文件或目录名称可以包含前缀来控制测试集的执行顺序
      • 例如01__some_tests.txt02__more_tests.txt 创建的测试用例集名称分别是 Some TestsMore Tests,并且前者会先执行
      • 规则也很明显,序号+双下划线
    • test suite的文档可以在初始化文件中写,也可以直接写在test case file中
    • Both the name and documentation of the top-level test suite can be overridden in test execution
      • This can be done with the command line options --name and --doc
  • 元数据
    • 通过在 Setting section中使用 Metadata 设置项来指定
    • 设置的元数据会在测试报告和日志文件中展示
      *** Settings ***
      Metadata    Version        2.0
      Metadata    More Info      For more information about *Robot Framework* see http://robotframework.org
      Metadata    Executed At    ${HOST}
      
    • 可以分成namevalue两部分
    • 同样的,可以通过--metadata command line 指定
  • Setup&Teardown
    • 测试套件的Setup在其中所有测试用例和子套件运行之前被执行,Teardown则是在之后执行
    • OK,到目前,应该明白了test case file和suite的关系,类似于python的类和对象,这里的类可以组合生成高级类从而有高级对象;最终是以套件的形式运行(方便组织和管理)
    • 感性认识,后面在实际案例中就可以具体理解
      test case file -> test suite(this file's cases)
      test case file directory -> high level test suite(test case files -> test suites -> cases)
      
    • 如果一个测试套件的Setup执行失败了,该套件下的所有子套件和用例会立即置为失败状态
      • 利用这种特性,可以来检验用例执行的必要前置条件是否满足

测试库

  • 测试库中包含底层的关键字(lowest-level keywords), 通常称之为 库关键字(library keywords)
  • user keywords 会调用这些底层关键字
  • 导入库
    • 可以Import,也可以Library导入
      • 当测试库在测试执行前不能导入, 只能在执行过程中通过某些关键字来启用时,使用import
    # 使用的位置也不一样
    *** Test Cases ***
    Example
        Do Something
        Import Library    MyLibrary    arg1    arg2
        KW From MyLibrary
    
    • 库可以使用参数和变量
    *** Settings ***
    Library    OperatingSystem
    Library    my.package.TestLibrary
    Library    MyLibrary    arg1    arg2
    Library    ${LIBRARY}
    
    • 大小写敏感,空白敏感
    • 可以用库名和库的路径导入
      • 安装的库在module search path中可以直接找到,但是自定义的库需要配置到里面
      • 使用路径就不需要了,如果库是文件,需要带上扩展名
    *** Settings ***
    Library    PythonLibrary.py
    Library    /absolute/path/JavaLibrary.java
    Library    relative/path/PythonDirLib/    possible    arguments
    Library    ${RESOURCES}/Example.class
    
  • 设置别名
    • 测试库的名称在日志文件中会在关键字的前面展示
      • 如果关键字重名,就要加上库名称做前缀
    • 库的名称一般就是实现该库的模块或类名,但有时需要改变
      • 需要不止一次的导入一个相同的库, 每次使用不同的参数. 如果每次是相同的名称则不可能做到
      • 库名非常长, 不方便. 比如, 有超长包名的Java库
      • 在不同的环境中使用不同的测试库, 但是希望以相同的名称引用它们
      • 库的名称起的不好, 有误导作用 (当然, 这时候更应该改名)
    • 指定新名称可以使用WITH NAME
      *** Settings ***
      Library    com.company.TestLib    WITH NAME    TestLib
      Library    ${LIBRARY}             WITH NAME    MyName
      Library    SomeLibrary    localhost        1234    WITH NAME    LocalLib
      Library    SomeLibrary    server.domain    8080    WITH NAME    RemoteLib	# 参数放在with name之前
      

标准库

  • 随 Robot Framework 版本一同发布的测试库称之为 标准库
  • 其中 BuiltIn 最特别,可以自动启用,无需导入
  • 其他标准库
    Collections
    DateTime
    Dialogs
    OperatingSystem
    Process
    Screenshot
    String
    Telnet
    XML
    
  • 还有远程库和外部库
  • 库文件放在automation/lib

变量

  • 一直在提到变量这个概念,看到这,相信已经知道的差不多了
  • 大部分情况下, 变量用于关键字的参数;当然,设置项也都支持用变量来指代设置值
  • 变量类型,和Perl语言很像
    • 标量 ${SCALAR}
    • 列表 @{LIST}
    • 字典 &{DICT},perl中用%,而且这里都要加花括号
    • 环境变量 %{ENV_VAR}
  • 推荐使用大写字母表示全局变量${PATH},小写字母表示局部变量${myVar}(或者驼峰)
    • 不区分大小写,下划线和空格也会被忽略

标量

  • 通常被赋值字符串
    *** Test Cases ***
    ${GREET} = Hello
    ${NAME} = 123
    
    Variables
        Log    ${GREET}
        Log    ${GREET}, ${NAME}	# 先转换成unicode字符串,123->‘123’,这里逗号将两个变量作为一个参数
    # 注:如果变量不是单独使用,即这里一个参数中两个及以上变量;its value is first converted into a string and then concatenated with the other data
    # 用到python的__str__方法,或者java的toString方法,返回字符串或return值
    

列表

  • 如果使用列表,里面的元素会分别传递给不同参数,下面两个例子等价
    *** Test Cases ***
    Constants
        Login    robot    secret
    
    List Variable
        Login    @{USER}
    
  • 从4.0版本开始,列表扩展可与列表项访问结合使用,总体和python一致
    *** Test Cases ***
    Nested container
        ${nested} =    Evaluate    [['a', 'b', 'c'], {'key': ['x', 'y']}]
        Log Many    @{nested}[0]         # Logs 'a', 'b' and 'c'.
        Log Many    @{nested}[1][key]    # Logs 'x' and 'y'.
    
    Slice
        ${items} =    Create List    first    second    third
        Log Many    @{items}[1:]         # Logs 'second' and  'third'.	切片操作什么的和python一致
    # 注:不允许字符串作为字符列表使用,但是其它的序列对象如元组或字典是可以的(类似列表的对象)
    
    Keyword    @{LIST}    @{ANOTHER}    @{ONE MORE}	# 注意,多个参数要用tab隔开,否则会做字符串处理
    
  • 有些场景不能使用列表变量传递,一般导入库和执行关键字不能使用
    *** Settings ***
    Library         ExampleLibrary      @{LIB ARGS}    # This works
    Library         ${LIBRARY}          @{LIB ARGS}    # This works	可以作为库的参数
    Library         @{NAME AND ARGS}                   # This does not work	不能直接传递库名,因为Library一次只能导入一个库,后面的会被当作参数
    Suite Setup     Some Keyword        @{KW ARGS}     # This works
    Suite Setup     ${KEYWORD}          @{KW ARGS}     # This works
    Suite Setup     @{KEYWORD}                         # This does not work	同样,参数可以,关键字名称不能使用列表,suite后只能跟一个关键字
    Default Tags    @{TAGS}                            # This works
    

字典

  • 和列表类似,能够以命名参数的形式,分别赋值给不同参数
    *** Test Cases ***
    Constants
        Login    name=robot    password=secret
    
    Dict Variable
        Login    &{USER}
        Keyword    positional    @{LIST}    &{DICT}	# 混用时要注意位置
    
    *** Settings ***
    Library        ExampleLibrary    &{LIB ARGS}
    Suite Setup    Some Keyword      &{KW ARGS}     named=arg	# 充当参数使用
    

环境变量

  • 就是操作系统的环境变量
    *** Test Cases ***
    Env Variables
        Log    Current user: %{USER}
        Run    %{JAVA_HOME}${/}javac
    
  • 可以在执行中设置,但是用例结束就会恢复

创建

  • 变量的创建在test case file的Variables section
    *** Variables ***
    ${NAME}         Robot Framework
    ${VERSION}      2.0
    ${ROBOT}        ${NAME} ${VERSION}
    ${NAME} =       Robot Framework		# = 不是必须的
    ${VERSION} =    2.0
    
    • 变量名也不是随便起的,例如 ${true} 就表示true,${None}就表示python的None
  • 标量值被分隔成多个参数的形式(tab)还是会以空格拼接
    *** Variables ***
    ${EXAMPLE}      This value is joined    together with a space
    ${MULTILINE}    SEPARATOR=\n    First line
    ...             Second line     Third line
    
  • 列表变量
    *** Variables ***
    @{NAMES}        Matti       Teppo
    @{NAMES2}       @{NAMES}    Seppo
    @{NOTHING}
    @{MANY}         one         two      three      four
    ...             five        six      seven
    # 前面的例子也看到使用关键字创建
    
  • 字典变量
    *** Variables ***
    &{USER 1}       name=Matti    address=xxx         phone=123
    &{USER 2}       name=Teppo    address=yyy         phone=456
    &{MANY}         first=1       second=${2}         ${3}=third
    &{EVEN MORE}    &{MANY}       first=override      empty=
    ...             =empty        key\=here=value		# 转义
    
    # 字典的获取,比较特殊
    &{USER}[name]
    ${USER.name}	# 注意,这里使用 $,和perl语言类似
    ${MANY.3}	# 不可以,${3}是一个变量
    
    • 字典变量中的项是有顺序
  • 变量文件
    • 使用变量文件可以给变量赋值为任意的对象,还可以动态地创建变量

    • 资源文件通过在 Settings 中设定 Resource 来引入

      *** Settings ***
      Resource    myresources.html
      Resource    ../data/resources.html
      Resource    ${RESOURCES}/common.tsv	# 推荐使用变量
      
      • 定义在资源文件中的用户关键字和变量在导入后即可使用
      • 该资源文件中从其它文件(测试库/资源文件/变量文件)导入的关键字和变量的关键字,也可用
      • 资源文件的整体结构和测试用例文件一样, 只不过其中不能包含测试用例(Test cases section)
      • 资源文件放在automation/resource下(n147-h183)
      # 相较Library更高级,Library定义的主要是关键字,而Resourse与test  case file极狐无异
      
      *** Settings ***
      Documentation     An example resource file	# 这个不会写入日志
      Library           Selenium2Library
      Resource          ${RESOURCES}/common.robot
      
      *** Variables ***
      ${HOST}           localhost:7272
      ${LOGIN URL}      http://${HOST}/
      ${WELCOME URL}    http://${HOST}/welcome.html
      ${BROWSER}        Firefox
      
      *** Keywords ***
      Open Login Page
          [Documentation]    Opens browser to login page		# 第一行写入日志
          Open Browser    ${LOGIN URL}    ${BROWSER}
          Title Should Be    Login Page
      
      Input Name
          [Arguments]    ${name}
          Input Text    username_field    ${name}
      
      Input Password
          [Arguments]    ${password}
          Input Text    password_field    ${password}
      
    • 不好意思,走错片场了,应该说变量文件,在 Settings 中设定 Variables 来引入

      # 类似的
      *** Settings ***
      Variables    myvariables.py
      Variables    ../data/variables.py
      Variables    ${RESOURCES}/common.py
      Variables    taking_arguments.py    arg1    ${ARG2}
      
      • 如果多个文件内的变量冲突,则最先导入的生效,资源文件亦是如此
      • 可以通过命令行 --variablefile myvariables.py 指定
  • 可以通过命令行设置变量
    --variable EXAMPLE:value	# 标量
    --variable HOST:localhost:7272 --variable USER:robot	# 字典
    
  • 关键字的返回值可以赋值给变量,不同的关键字之间就可以交互了
    *** Test Cases ***
    Returning
        ${x} =    Get X    an argument
        Log    We got ${x}!
        ${a}    ${b}    ${c} =    Get Three
    
    Example
        ${list} =    Create List    first    second    third	# 都可以用标量接收,也可以直接@{list}
        Length Should Be    ${list}    3
        Log Many    @{list}	# 能当列表用,能当字典用
    
    • 变量类型视值而定

关键字创建

  • BuiltIn_ 测试库提供了几个可以在测试执行时动态设置变量的关键字
  • Set Test Variable 设置的变量在当前测试用例的作用域内处处可用
  • Set Suite Variable 创建的变量在当前执行的测试套件内处处可见,子套件就不可见
  • Set Global Variable 创建的变量在设置之后全局可见,谨慎使用!

其他

  • 内置变量,全局的
  • 操作系统变量
  • 数字变量
  • 布尔值
  • 空格和空字符串:${SPACE}${EMPTY}
  • 自动变量

高级特性

用户关键字

  • 貌似来到了最关键的部分,User Keywords
  • 组合已有的关键字来创建新的高层次的关键字,被称之为 用户关键字

语法

  • 大部分和test case的语法一致,关键字名,参数…
  • case中使用关键字,要传参;这里是定义关键字
    • 所以,前面的感性认识不太恰当,test case相当于函数调用,Keywords才是def
    *** Keywords ***
    Open Login Page
        Open Browser    http://host/login.html
        Title Should Be    Login Page
    
    Title Should Start With
        [Arguments]    ${expected}
        ${title} =    Get Title
        Should Start With    ${title}    ${expected}
    
    • 在资源文件中创建的关键字在导入了该资源文件后即可使用
    • 其它文件中创建的关键字只在所在文件内可用
    • 关键字名称往往具有描述性,有时可能是一句话甚至段落
  • 设置项
    [Documentation]
    	用户关键字文档.
    [Tags]
    	Sets tags for the keyword.
    [Arguments]
    	指定用户关键字的参数	specifies
    [Return]
    	Specifies 用户关键字返回值
    [Teardown]
    	Specify 用户关键字的Teardown
    [Timeout]
    	Sets the possible user keyword timeout. Timeouts are discussed in a section of their own.
    
    • 在文档开始前使用 *DEPRECATED* 可以标记该用户关键字已经不建议使用
    • 关键字的标签不受Force/Default Tag影响,但可以在文档中打标签!
    *** Keywords ***
    Settings tags using separate setting
        [Tags]    my    fine    tags
        No Operation
    
    Settings tags using documentation
        [Documentation]    I have documentation. And my documentation has tags.
        ...                Tags: my, fine, tags		# 牛不牛?
        No Operation
    
    # 避免使用robot-
    
    • 参数必须使用[Argument]设置,参数的名称和变量一样!什么标量啊花括号啊之类的
    *** Keywords ***
    One Argument
        [Arguments]    ${arg_name}
        Log    Got argument ${arg_name}
    
    Three Arguments
        [Arguments]    ${arg1}    ${arg2}    ${arg3}
        Log    1st argument: ${arg1}
        Log    2nd argument: ${arg2}
        Log    3rd argument: ${arg3}
    
    # 带默认值的参数
    One Argument With Default Value
        [Arguments]    ${arg}=default value
        [Documentation]    This keyword takes 0-1 arguments
        Log    Got argument ${arg}
    
    # 可变参数
    Any Number Of Arguments
        [Arguments]    @{varargs}
        Log Many    @{varargs}
    
    # 同样的,还有任意命名参数
    Kwargs Only
        [Arguments]    &{kwargs}
        Log    ${kwargs}
        Log Many    @{kwargs}
    
  • 关键字名称中嵌入参数,关键字工厂的感觉
    *** Keywords ***
    Select ${animal} from list
        Open Page    Pet Selection
        Select Item From List    animal_list    ${animal}
    
    • 关键字被调用时自然而然的传递给对应位置的参数
    • 嵌入参数可能会因为实参格式问题发生错误,一个简单的解决方法是把参数用引号括起来
      • 例如 Select “${city}” “${team}”), 然后调用时同样使用引号传参 Select “Los Angeles” “Lakers”)
    • 还可以通过正则表达式解决
    *** Test Cases ***
    Example
        I execute "ls"
        I execute "ls" with "-lh"
        Today is 2011-06-27	
    
    *** Keywords ***
    I execute "${cmd:[^"]+}"		# 表示该参数不能包含任何引号,就能和下面的关键字区分开,避免把 ls" with "-lh 当成参数
        Run Process    ${cmd}    shell=True
    
    I execute "${cmd}" with "${opts}"
        Run Process    ${cmd} ${opts}    shell=True
    
    Today is ${date:\d{4\}-\d{2\}-\d{2\}}	# 正则中的花括号必须转义,否则变量会提前结束
    	Log    ${date}
    
    • 也就是说,推荐使用引号+正则的形式
    • 这里有个嵌入变量的行为驱动的例子:体会嵌入的灵活性
    *** Test Cases ***
    Add two numbers
        Given I have Calculator open	# Given, When 和 Then不是关键字名称的一部分
        When I add 2 and 40
        Then result should be 42
    
    Add negative numbers
        Given I have Calculator open
        When I add 1 and -2
        Then result should be -1
    
    *** Keywords ***
    I have ${program} open
        Start Program    ${program}
    
    I add ${number 1} and ${number 2}
        Input Number    ${number 1}
        Push Button     +
        Input Number    ${number 2}
        Push Button     =
    
    Result should be ${expected}
        ${result} =    Get Result
        Should Be Equal    ${result}    ${expected}
    
  • 返回值
    • 可以通过Return 设置
    *** Keywords ***
    Return One Value
        [Arguments]    ${arg}
        Do Something    ${arg}
        ${value} =    Get Some Value
        [Return]    ${value}		# 放在一个标量保存起来!
    
    Return Three Values
        [Return]    foo    bar    zap
    
    • 也可以通过特殊关键字返回值
    *** Keywords ***
    Return One Value
        [Arguments]    ${arg}
        Do Something    ${arg}
        ${value} =    Get Some Value
        Return From Keyword    ${value}
        Fail    This is not executed
    
    Find Index		# 如何在for循环中使用特殊关键字返回值
        [Arguments]    ${element}    @{items}
        ${index} =    Set Variable    ${0}
        :FOR    ${item}    IN    @{items}
        \    Return From Keyword If    '${item}' == '${element}'    ${index}
        \    ${index} =    Set Variable    ${index + 1}
        Return From Keyword    ${-1}    # Could also use [Return]
    

Teardown

  • 和test case的一样,可以设置teardown
    *** Keywords ***
    With Teardown
        Do Something
        [Teardown]    Log    keyword teardown
    
    Using variables
        [Documentation]    Teardown given as variable
        Do Something
        [Teardown]    ${TEARDOWN}
    

高级特性

  • 处理同名关键字
  • 超时处理
  • FOR循环
  • 条件表达式
  • 关键字并发执行

小结

  • 这节主要介绍robot framework的基本概念和语法
  • 包括设置/文档/变量/测试库/用户关键字/测试用例/测试用例文件/测试套件

你可能感兴趣的:(Perl,python,framework)