zhenl

最近项目中使用了开源的自动化测试框架Robot Framework,总结一下,希望对大家有帮助。

安装

首先,确保系统安装了python。然后就可以使用pip安装了:
pip install robotframework
安装完成后,使用下面的命令查看版本:
robot --version
然后我们可以创建一个简单的测试脚本:

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

然后,可以使用robot运行这个测试脚本:
robot helloworld.robot
运行结果如下:

还可以安装使用IDE工具RIDE,使用这个工具可以很方便地创建自动测试项目,编写测试脚本。使用pip可以很方便地安装:

pip install robotframework-ride

字符串操作

Robot Framework字符串拼接需要使用catenate关键字,下面的代码将Hello和World合并

${s}=  catenate   Hello  World

得到的结果是Hello World。如果我们希望中间没有空格,需要使用SEPARATOR参数:

${s}=  catenate    SEPARATOR=   Hello   World

这样得到的结果就是HelloWorld。SEPARATOR参数声明了拼接中的连接字符,下面的代码输出结果是Hello|World:

${s}=  catenate    SEPARATOR=|   Hello   World

如果字符串中包含特殊字符,比如#等,需要使用转义,示例如下:

${k}=    catenate    SEPARATOR=    \#val_    ${key}    \#

使用String库中的Split String关键字可以将字符串分隔,比如v1,v2,v3使用逗号分隔,处理后的结果保存在列表中。使用示例如下:

    FOR    ${str}    IN    @{dic}
        ${ss}=    String.Split String    ${str}    :
        Set To Dictionary    ${data}    ${ss}[0]    ${ss}[1]
    END

这个例子中,传入参数的键和值用冒号分隔,比如:
Name:Jone Age:13
这里使用Split String 将键和值分开,保存到字典中。

需要注意的是,使用Split String 关键字,需要引用String库。

测试Web API

使用Robotframework的RequestsLibrary可以很方便地测试Web Api。首先需要安装RequestLibrary:
pip install robotframework-requests
然后就可编写测试脚本了。
首先需要声明使用Library:

*** Settings ***
Library    RequestsLibrary

接下来定义访问的地址:

*** Variables ***
${HOST}    http://localhost/myapi

然后就可以写用例了:

*** Test Cases ***
API Test Example
	Create Session    my_session    ${HOST}
	${headers}=    Create Dictionary    Accept=application/json    Content-Type=application/json    charset=utf-8

	# POST request with params
	${data}=    Create dictionary    field1=value1    field2=value2
	${response}=    Post Request    my_session    my-endpoint    headers=${headers}    data=${data}

	Should be equal as strings    ${response.status_code}    200
	Log    ${response} 

这里使用的是POST方法,向api发送的键值对定义在data中,这里使用了创建键值对字典的关键字Create Dictionary。返回的对象定义在变量${response}中,使用Post Request可以执行访问。

数据库相关测试

在测试时,我们可以直接访问数据库查看数据是否正确,这时可以使用Robot Framework DatabaseLibrary。

首先从https://github.com/franz-see/Robotframework-Database-Library下载,解压后,执行python setup.py install进行安装。安装完成后就可以使用了。

在RIDE中创建一个新的测试,在Library中引入DatabaseLibrary,按F5打开SearchKeywords窗口,选择DatabaseLibrary,可以列出所有相关的关键字:

还需要安装特定的数据库访问模块,如果访问sqlserver,可以安装pymssql:

pip install pymssql

然后就可以写测试用例了,比如:

*** Settings ***
Library           DatabaseLibrary

*** Test Cases ***
DBTEST
    Connect To Database Using Custom Params    pymssql    database='dbname',user='username',password='pwd',host='localhost'
    Table Must Exist    AUTH_USER_TB
    Disconnect From Database

Database Library中有两个关键字可以用来连接数据库:
Connect To DataBase 和 Connect To Database Using Custom Params,Connect To DataBase需要声明参数或者将参数保存在配置文件中,参数如下:

dbapiModuleName=None, dbName=None, dbUsername=None, dbPassword=None, dbHost=localhost, dbPort=5432, dbConfigFile=./resources/db.cfg

这里需要注意,如果没有显示声明dbName、dbUserName、dbPassword、dbHost或者dbPort,都会去指定的配置文件中查找相应的配置项,如果找不到配置文件,就会报错。配置文件的格式如下:

[default]
dbapiModuleName=pymysqlforexample
dbName=yourdbname
dbUsername=yourusername
dbPassword=yourpassword
dbHost=yourhost
dbPort=yourport

可以使用的关键字如下:

  • Check If Exists In Database:参数为select语句,如果有查询结果,返回ture,否则为false。
  • Check If Not Exists In Database: 与上面的关键字结果相反。
  • Delete All Rows From Table:参数为表名,删除表中所有数据。
  • Description: 参数为select语句,返回为查询结果字段的描述数组,比如name='id', type_code=1043, display_size=None, internal_size=255, precision=None, scale=None, null_ok=None)。
  • Execute Sql Script: 执行sql脚本,多个sql语句使用分号分隔。
  • Query: 执行查询语句。
  • Row Count: 返回查询语句的行数。
  • Row Count Is 0: 返回查询行数是否为0。
  • Row Count Is Equal To X :返回查询行数是否为给定的行数X。
  • Row Count Is Greater Than X: 返回查询行数是否大于给定的行数X。
  • Row Count Is Less Than X: 返回查询行数是否小于给定的行数X。
  • Table Must Exist: 指定表是否存在。

自定义关键字

使用Robotframework对Api接口进行测试,每次测试都需要先登录,为了减少重复的登录脚本,使用Robotframework自定义关键字简化登录过程的脚本。代码如下:

*** Keywords ***
登录到平台
    [Arguments]    ${host}    ${username}    ${password}
    Create Session    my_session    ${host}
    ${data}=    Create dictionary    UserName=${username}    Password=${password}
    ${response}=    POST On Session    my_session    url=/api/Account/Login    json=${data}
    Log    ${response}
    [Return]    my_session

为了方便使用,我们使用中文作为关键字的名称。然后定义三个输入变量,${host}是需要登录的网址,${username}和${password}是用户名和密码。使用POST On Session实现登录,登录后返回登录过程创建的会话。这个关键字可以在测试用例中使用,比如:

*** Test Cases ***
TestLogin
    ${mysession}=    登录到平台    host=${HOST}    username=saleuser1    password=1
    ${datalist}=    Create dictionary    WorkFlow_Name=LeaveApply1
    ${responselist}=    POST On Session    ${mysession}    url=${GetActivateListUrl}    json=${datalist}
    Log    ${responselist}

我们可以将自定义的关键字保存在资源文件中,便于在多个测试用例中共用。资源文件的结构与测试文件基本相同,只是没有测试用例,变量和自定义关键字部分完全相同。在测试文件的设置部分引用资源文件,比如:

*** Settings ***
Library           RequestsLibrary
Resource          ../../Resources/flowresources.robot

资源文件的位置相对于当前路径,路径中也可以包含变量,比如${RESOURCES}/common.tsv。
如果多个资源文件中包含相同的自定义关键字,在使用这些关键字时,需要使用资源文件名作为前缀。如果多个资源文件中包含相同的变量,那么先加载的变量起作用。

很多情况下,我们需要自定义关键字可以接收多个参数,且参数的个数不确定,这种情况下,可以将参数声明为列表,使用@修饰符,示例代码如下:

MultiArguments
    [Arguments]    ${par1}    @{dic}
    Log    ${par1}
    FOR    ${v}    IN    @{dic}
        Log    ${v}
    END

在上面的例子中${par1}是固定参数,后面的@{dic}是可变参数列表,在自定义关键字中采用循环处理列表中的参数。调用的示例如下:

MultiArgumetns   para1  u1  u2  u3  u4

为Robotframework开发自定义库

Robotframework基于Python开发,我们使用Python开发自定义库,对Robotframework提供扩展。开发和使用都非常简单,由于python是解释语言,自定义库不需要编译部署等等步骤,使用任何文本编辑器都可以实现。这里通过实现一个简单的需求说明创建和使用过程。需求很简单,需要从一个字符串中获取flowid=后面的值。
首先我们创建一个python文件,代码如下:

def get_flow_id(url):
    idx = url.index('flowid=')+7
    le = len(url)
    flow_id = url[idx:le]
    return flow_id

然后就可以在robot文件中引用这个库了,在Settings中增加:

*** Settings ***
Library           ../pylibs/getflowid.py

这里库的位置相对于当前文件的位置。
在测试用例或者关键字中就可以使用自定义库中定义的新关键字了,这里get_flow_id对应的新关键字是Get Flow Id,"_"符号被空格替换,并且后面的字符变为大写。下面是使用的示例:

${fid}    Get Flow Id    ${rurl}

相关文章: