前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在培训机构也学不到的Robot Framework自动化测试企业级实战教程

在培训机构也学不到的Robot Framework自动化测试企业级实战教程

作者头像
Bug挖掘机
发布2022-09-28 15:15:46
1.5K0
发布2022-09-28 15:15:46
举报
文章被收录于专栏:测试开发基础

前言

大家好,我是洋子,今天给大家分享一下Robot Framework自动化测试框架的使用教程,Robot Framework是一个可扩展关键字驱动的测试自动化框架,可用于做接口、UI自动化,并且可以使用 Python 或者Java 去编写测试用例依赖的lib库,是一款非常强大的测试框架

看了网上大量文章,基本都是使用Robot Framework的RIDE来进行测试,RIDE即为Robot的图形化编辑界面,操作起来并不是很方便,所以本文将教大家直接使用PythonRobot命令来进行自动化测试,便于用例执行和扩展,大厂基本都在这样用,便于和CI(持续集成)流水线结合执行测试用例

在编写用例的基础之上,我还会教大家设计、搭建自动化测试框架,满足企业级的自动化测试需求

本期教程包括以下部分内容

  • Robot Framework 环境搭建
  • Robot Framework 关键字参数定义
  • 搭建自动化测试框架
  • 编写测试用例
  • 执行测试用例
  • 生成测试报告

环境搭建

Robot Framework是用Python实现的,也可以在Jython(JVM)和 IronPython(.NET)解释器上运行。在安装框架之前,一个明显的前提条件是安装所需的解释器

本文只介绍使用Python去安装Robot Framework框架以及使用Python去编写robot框架的自定义参数、lib库等,因为这是最主流也是最方便的使用方式

下载、安装Python 3.x

Python 2 在2020年已停止维护,所以建议大家都安装Python 3.x 版本

Unix & Linux 安装 Python

  • 安装方法参考文章 https://www.linuxprobe.com/linux-centos7-python3.html
  • 安装方法参考文章 https://blog.csdn.net/L_15156024189/article/details/84831045

Windows 安装 Python

  • 打开官网下载https://www.python.org/downloads/windows/ 下载安装包
  • 安装方法参考文章 https://www.runoob.com/python/python-install.html

MAC 安装 Python

  • 方法1: 打开官网 https://www.python.org/downloads/mac-osx/ 下载最新版安装包
  • 方法2: 使用 homebrew 安装python3 环境,homebrew安装方法见https://blog.csdn.net/u011035397/article/details/115862286,安装完毕后执行命令 brew install python3即可

安装robotframework库

安装robotframework,最简单的方式是通过pip安装

代码语言:javascript
复制
pip install robotframework

安装requests库

python的requests库,用来发送HTTP请求,做接口自动化测试需要使用到

代码语言:javascript
复制
pip install requests

在mac 命令行下使用pip命令 前面 还需要加sudo命令,否则会提示无权限

安装selenium2library库

安装 selenium2library库,用来做Web UI自动化测试(若只使用robot框架做接口自动化,此库可不安装)

代码语言:javascript
复制
pip install robotframework-selenium2library

到此为止,Robot Framework 框架以及所需要的依赖环境全部安装完毕

关键字参数

前言我们提到Robot Framework是关键字驱动的测试自动化框架,这个关键字可以理解成Robot框架的语法,掌握了关键字的含义,我们才能更好的编写测试用例,在Robot框架中有两类关键字,一类是系统自带的关键字,另一类是自定义关键字。当系统关键字不满足我们的测试需求时,就可以基于Python自定义关键字,然后使用自定义的关键字去编写测试用例

系统关键字

为方便讲解,首先创建三个list变量:list_a、list_b、list_c;以及两个scalar变量(scalar变量就是一种标量变量,存放字符串或者数字):string和name。本节知识可先跳过,后面使用到做参考即可

代码语言:javascript
复制
@{list_a}   create list   1   a   ${21}   21   12
@{list_b}   set variable   1.0   a   ${21}   21   21
@{list_c}   create list    

${string}    set variable   pengliwen is in hangzhou   
${name}   set variable   plw 

备注:以下提供的用例都是断言成功

  • should contain 、 should not contain 与should contain x times
代码语言:javascript
复制
should contain   ${list_b}   1.0   
should not contain   ${list_b}   1   
should contain x times   ${list_b}   21   2

说明:变量{list_b}包含对象1.0而不包含对象1,且对象21在变量{list_b}出现了两次。

  • should be empty 与 should not be empty
代码语言:javascript
复制
should be empty   ${list_c}
should not be empty   ${list_a}

说明:变量{list_c}没有赋值,所以为空;相反,变量{list_a}有赋初始值,故为非空。

  • should be equal 与 should not be equal
代码语言:javascript
复制
should be equal   ${list_a[1]}   ${list_b[1]}
should not be equal   ${list_a}   ${list_b}

说明:{list_a[1]}=a,{list_b[1]}=a故两个对象相等;而{list_a}和{list_b}有元素不一致,这两个对象不相等

  • Should Be Equal As Numbers 与 Should not Be Equal As Numbers
代码语言:javascript
复制
Should Be Equal As Numbers   ${list_b[0]}   1.0000
Should not Be Equal As Numbers   ${list_b[0]}   1.1

说明:${list_b[0]}=1,忽略精度,故与1.0000相等;而即使是忽略精度,1与1.1还是不相等的;

  • Should Be Equal As Integers与Should not Be Equal As Integers
代码语言:javascript
复制
Should Be Equal As Integers   ${list_a[3]}   ${list_b[3]}
Should not Be Equal As Integers   ${list_a[4]}   ${list_b[4]}

说明:{list_a[3]}=21,{list_b[3]}=21,而系统默认为字符串格式的“21”,故需要转化为整数类型,转化为整数后两个对象相等;{list_a[4]}=12,{list_b[4]}=21,即使转化为整数后两个对象依旧是不相等;

  • Should Be Equal As Strings与Should not Be Equal As Strings
代码语言:javascript
复制
Should Be Equal As Strings   ${list_a[2]}   ${list_b[2]}
Should not Be Equal As Strings   ${list_a[0]}   ${list_b[0]}

说明:{list_a[2]}={21},{list_b[2]}={21},而均为数值型的21,故需要转化为字符串类型,转化为字符串后两个对象相等;

  • Should Be True与Should not Be True
代码语言:javascript
复制
Should Be True   ${list_a[0]} < 10
Should not Be True   ${list_a[0]} < 1

说明:${list_a[0]}=1(字符串类型),其ASCII值比字符串10的ASCII值小;

  • Should start With与Should not start With
代码语言:javascript
复制
Should start With   ${string}   peng
Should not start With   ${string}   h

说明:${string}=”pengliwen is in hangzhou“是以peng开头,而非以h开头;

  • Should End With与Should not End With
代码语言:javascript
复制
Should End With   ${string}   hangzhou
Should not End With   ${string}   pengliwen

说明:${string}=”pengliwen is in hangzhou“是以hangzhou结尾,而非以pengliwen结尾;

  • should match与should not match
代码语言:javascript
复制
should match   ${name}   p??
should not match   ${string}   h?*

说明:模式匹配和shell中的通配符类似,它区分大小写,'*'匹配0~无穷多个字符,“?”单个字符

${name}=plw,由以p开头的三个字母组成

  • Should Match Regexp与Should not Match Regexp
代码语言:javascript
复制
Should Match Regexp   ${name}   ^\\w{3}$
Should not Match Regexp   ${name}   ^\\d{3}$

说明:反斜杠在测试数据是转义字符,因此模式中要使用双重转义;'^'和'$'字符可以用来表示字符串的开头和结尾

${name}=plw,是有三个字母--w{3}组成,而不是由三个数字--d{3}组成。

自定义关键字

除了系统关键字,我们还可以编写Python文件自定义关键字,格式如下

代码语言:javascript
复制
import requests
from robot.api.deco import keyword

class HttpLibrary(object):
    """ Http Request Library """

    def __init__(self):
        """ 初始化 session """
        self.session = {}

    @keyword('Create Http')
    def create(self, alias, url, headers=None, cookies=None, timeout=None):
        """ 创建一个 Http 连接代理 """
        pass

    @keyword('Post Http')
    def post(self, alias, path='', data='{}', isJsonStr=False):
        """ 执行 POST 请求 """
		pass
 
    @keyword('Get Http')
    def get(self, alias, path='', data='{}', is_log=True):
        """ 执行 GET 请求 """
		pass
 
    @keyword('Json Post Http')
    def jsonpost(self, alias, path='', data='{}'):
        """ 执行 POST 请求(body为json格式) """
		pass  

上面的Python文件定义了一个类,可以看到该文件当中除了init构造方法,其他每个方法都由keyword装饰器修饰,分别定义了Create HttpPost HttpGet HttpJson Post Http这4个自定义关键字,如果还需要其他自定义关键字,按照这个结构继续添加就行

至于自定义关键字和系统自带的关键字如何使用,在下面 创建测试用例 章节会讲到

搭建测试框架

现在虽然安装好了robotframework的运行环境,也能直接开始编写测试用例,但我们还要想到一个问题,如果用例数量非常庞大怎么管理,工具类的lib库管理等问题,就像设计房子的结构图

我们还需要设计一个简单的测试框架的架构,基于架构去填充自己的测试用例,架构如下:

代码语言:javascript
复制
- case目录
	- 模块名目录_01
		-  自动化case_01
		-  自动化case_02
	- 模块名目录_02
- lib目录
  • case目录:用来存放自动化case,被测系统可能涉及的模块较多,所以还建了一个二级目录来管理不同模块的case
  • lib目录:用来放公有的工具类,这些工具类已经封装成自定义关键字,方便用例调用,lib目录下的工具类可以根据自己的需求进行编写,比如操作数据库、发送网络请求、操作列表list、操作字典dict等等

创建测试用例

robotframework框架里定义的一个测试用例,就是一个以robot后缀结尾的文件,通用的用例文件内容结构如下:

代码语言:javascript
复制
# -*- coding: robot -*-

*** Settings ***
Documentation    测试集合描述
Library        ./lib/HttpLibrary.py
Library        DateTime
Library        json
Library        Collections

*** Variables ***
${参数1}=   xxx
${参数2}=   yyy

*** Keywords ***
关键字名称
    关键字逻辑

*** Test Cases ***
测试用例标题
    [Tags]    DEBUG
    [Documentation]    测试用例描述
    关键名称 ${参数1} ${参数2}
  • Settings:用于引入资源文件
  • Variables:定义变量,=和变量值之间需要空4个空格
  • Keywords:定义关键字,用于测试用例编写当中
  • Test Cases:测试用例的逻辑,应包含测试用例前置步骤、发送请求、返回结果断言等

但在我们实际编写用例的时候,一个用例并不需要SettingsVariablesKeywordsTest Cases 4个部分都包含,我们可以做一些调整,方便用例管理。具体的调整方法就是,创建一个base.robot,这个用例文件没有具体的case逻辑Test Cases这部分,而是将所有case需要用到的公有信息抽取出来,如需要引入的资源文件等等,这样做可以简化其余具体的case,去掉冗余信息

下面我以一个实际的接口测试自动化案例举例子,base.robot内容如下:

代码语言:javascript
复制
# -*- coding: robot -*-

*** Variables ***
# 执行接口自动化的测试环境
${case_httpurl}=    http://ip:port

${url_01}=    api_01?param_1=xxx&param_2=yyyy
${url_02}=    api_02?param_1=xxx&param_2=yyyy
${url_03}=    api_03?param_1=xxx&param_2=yyyy
${url_04}=    api_04?param_1=xxx&param_2=yyyy

&{cookies}=    BDUSS=xxxx

*** Settings ***
Documentation    xxx模块测试用例集合
Library        ./lib/DictLibrary.py
Library        ./lib/ListLibrary.py
Library        ./lib/HttpLibrary.py
Library        ./lib/LiveshowClientCommon.py
Library        ./lib/ImLiveshowCommon.py
Library        ./lib/DBOperation.py
Library        ./lib/YamlSchemaValidatorLibrary.py
Library        DateTime
Library        json
Library        Collections

*** Keywords ***
Init Base
    [Documentation]    全局关键字初始化
    ${headers}    Create Dict    {"Content-type": "application/x-www-form-urlencoded"}
    Create Http    httpProxy    ${case_httpurl}    headers=${headers}    cookies=&{cookies}    timeout=500000

base.robot包含了Variables、Settings、Keywords三个部分,base.robot只是集成用例的公有信息,所以并没有Test Cases这部分

在Variables中,我们定义了3种类型的变量,用来存放测试环境ip和端口、接口path以及cookies

Settings中则是引入lib目录下的工具类,这些工具类里面封装好了自定义参数,也可以引用python自带的工具库DateTimejsonCollections等等。

Keywords中是定义了一个自定义关键字名叫Init Base,这个关键字用于初始化,Init Base关键字的逻辑共3行代码

先看一下第2行(如下图),Create Dict这个自定义关键字是从./lib/DictLibrary.py获取到的,为什么能获取到呢,因为我们在Settings部分用系统关键字Library已经导入该文件了,就和python导入包import作用一样

代码语言:javascript
复制
${headers}    Create Dict    {"Content-type": "application/x-www-form-urlencoded"}

对于Create Dict的逻辑如下,传入value参数,经过json反序列化,返回字典类型。所以经过执行上面这段代码后,会给${headers}赋值一个字典类型

代码语言:javascript
复制
@keyword('Create Dict')
def create(value=None):
    """ 创建一个字典值 """
    if value is None:
        return {}

    if not isinstance(value, dict):
        try:
            value = eval(value)
        except Exception as e:
            pass

    if not isinstance(value, dict):
        try:
            value = json.loads(value)
        except Exception as e:
            pass
    if not isinstance(value, dict):
        raise Exception('[关键字使用不正确] Create Dict 的参数需为 dict 格式')
    return value

再看下Init Base关键字的第3行代码(如下图),Create Http是一个自定义关键字,从./lib/HttpLibrary.py获取到,传入了5个参数。这里注意一下robot case的变量定义,可以采用“变量标识符”($、@、&、%)+大括号{}+变量名来表示,注意第一个参数,是一个字符串常量httpProxy,并不是一个变量

代码语言:javascript
复制
Create Http    httpProxy    ${case_httpurl}    headers=${headers}    cookies=&{cookies}    timeout=500000

到这里base.robot的内容就讲完了,接下来我们看下具体的测试用例case该怎么写,用例代码如下

代码语言:javascript
复制
*** Settings ***
Documentation    用例描述
...    author by yangzi
Force Tags     标签名
Resource       base.robot
Suite Setup    Init Base

*** Variables ***

${room_id}=   ''
${im_sdk_version}=   '7700016'

*** Test Cases ***
Normal Procedure
    [Documentation]    用例描述
    [Tags]    P1

    #获取参数
    ${params}=    Create Dict      {'room_id':${room_id},'im_sdk_version':${im_sdk_version}}
    #发送请求,获取结果
    ${res}=    Post Http    httpProxy    ${url_01}   ${params}
    
    # 打印log
    log    ${res}
    
    Should Be Equal As Integers    ${res.json()['errno']}    0      #成功
    Validate With Yaml     ./xxx.yaml    ${res.json()}

这个robot case还是有3部分组成,分别是Settings、Variables、Test Cases。Settings部分使用Resource系统关键字导入base.robot,因为我们要使用到base.robot定义的关键字,Suite Setup也是一个系统关键字,即在执行该用例时,会首先运行此部分,这里我们看到是执行了Init Base关键字,这个关键字就是在base.robot里面定义的

在Test Cases部分,我们首先是组装了参数,然后执行Post Http关键字发送http请求,最后使用系统关键字Should Be Equal As Integers进行结果断言,是否返回结果json当中errno字段是否为0,而这里我们还用到了yaml文件去进行结果断言,yaml文件格式如下:

代码语言:javascript
复制
status: 0
errno: 0
msg: success
data:
  msg: ''
  user_cert:
    status: !type_int
  can_live: !type_int
  user_type: !type_int
  can_sale_goods: !py_def >
    def judge_templateid(data):
      if data in (0,1):
        return  True
      return  False

为什么要用yaml断言,是因为某些接口返回字段非常多或者返回字段是列表等等,不太方便直接在case当中直接断言

具体yaml文件的详细使用方法,以及上面使用到的Validate With Yaml自定义参数逻辑,在以后的文章我会单独说明,一般情况下case断言我们使用系统关键字Should Be Equal As Integers或者Should Be Equal就行

执行测试用例

执行用例仅需一条命令即可,常用命令如下:

代码语言:javascript
复制
#执行单个case,文件名mysql.robot
 robot -P . ./demo/mysql.robot
#执行demo目录下所有case
 robot -P .  demo/
#执行当前目录下所有case
 robot -P .  ./
#执行当前目录下所有以robot后缀结尾的用例文件
robot -P .  ./*.robot

命令解读

  • robot 是运行命令
  • -P . 是将工作目录指定为用例根目录(无论如何都需要指定为用例根目录)
  • demo/mysql.robot 为要执行的用例

生成测试报告

在执行完测试用例后,我们可以看到执行结果,看到pass就是case运行通过了

同时产生了三个测试报告,可使用浏览器打开。如果我们在编写测试用例时,使用了log关键字,测试报告里面也可以查看到,在case运行失败时,我们可以手动添加log进行调试,非常有用

结尾语

好了,到这里恭喜你已经成功学会了Robot Framework的基本使用方法,本文主要介绍了使用Robot框架去进行接口自动化测试,同样Robot Framework可以结合Selenium、Appium做UI自动化,除此以外,本文还提到接口断言使用Yaml文件,介于篇幅太长,在以后的文章中,我会继续更新。另外本文涉及的代码涉及到公司敏感性,暂不开源,大家可以自己动动手实践

作为一个软件测试人员,除了手工测试外,还是非常有必要去掌握自动化测试,此篇文章凝结了真实企业级自动化测试实战经历,

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试开发Guide 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 环境搭建
    • 下载、安装Python 3.x
      • 安装robotframework库
        • 安装requests库
          • 安装selenium2library库
          • 关键字参数
            • 系统关键字
              • 自定义关键字
              • 搭建测试框架
              • 创建测试用例
              • 执行测试用例
              • 生成测试报告
              • 结尾语
              相关产品与服务
              持续集成
              CODING 持续集成(CODING Continuous Integration,CODING-CI)全面兼容 Jenkins 的持续集成服务,支持 Java、Python、NodeJS 等所有主流语言,并且支持 Docker 镜像的构建。图形化编排,高配集群多 Job 并行构建全面提速您的构建任务。支持主流的 Git 代码仓库,包括 CODING 代码托管、GitHub、GitLab 等。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档