HyRobot


安装 黑羽robot

首先确保你电脑上安装好了 Python 3.7 或者 3.8 版本的解释器

安装RF

黑羽robot基于Robot Framework ,所以必须先安装RobotFramework

直接执行如下Pip命令即可:

pip install robotframework 

安装黑羽robot

点击这里下载黑羽robot项目包

解压下载的zip包,会产生一个名为 autotest_hyrobot 的目录, 这就是hyrobot的自动化项目目录。

你修改该目录的名字,比如我们要讲解 自动化测试 白月SMS系统 , 就可以改名为 autotest_bysms

建议:用PyCharm 等IDE直接打开项目文件夹,一定要 确保 hyrobot 目录 在项目根目录下面,如下

image

项目目录结构

黑羽robot 项目目录中包含

  • cases 目录

    里面存放 自动化测试用例代码

  • cfg 目录

    里面存放 配置文件

  • hyrobot 目录

    里面存放 hyrobot库 和 工具 代码, 开发者不需要 修改里面的内容

  • lib 目录

    里面存放 自动化测试用例 使用的 库

  • run.bat

    Windows下 运行 黑羽robot, 执行自动化测试 的 脚本

  • run.sh

    苹果 MacOS 下 运行 黑羽robot, 执行自动化测试 的 脚本

    注意:

    苹果用户,需要先执行 chmod +x run.sh 增加执行权限

    运行测试时,执行 ./run.sh 命令

用例文件的编写、执行、产生日志报告

编写用例

用例文件格式如下:

文件里面每个类对应一个用例。

类的 name 属性 指定 用例名

类的 teststeps 方法 里面的代码 就是 测试步骤

特别注意 : 用例类名 一定要保证唯一 ,推荐包含用例编号。比如

# 类名保证唯一,推荐包含用例编号
class UI_0101:
    # 测试用例名字
    name = '管理员首页 - UI-0101'

    # 测试用例步骤
    def teststeps(self):

代码最前面加上

from hyrobot.common import *

导入 hyrobot 库,库里面有一些函数 和

声明每个步骤使用 STEP 库函数

打印信息用 INFO 库函数

检查点用 CHECK_POINT 函数。

执行用例

执行用例需要

  • 打开命令行窗口
  • 进入到自动化项目根目
  • 运行 run.bat

日志和报告

执行完后,就会产生 汉化的 日志 和 报告。

数据驱动用例

点击这里,边看视频讲解,边学习以下内容

做过自动化测试的朋友经常听说过 数据驱动 (或者面试的时候被问到过)。

什么是数据驱动?

如果有一批测试用例,具有 相同的测试步骤 ,只是 测试参数数据不同

自动化测试时,把测试数据从用例代码中 分离 开来,以后增加新的测试用例,只需要修改数据。

这就是数据驱动。

举个例子:

某系统 登录功能的测试,有一批测试用例,其执行的步骤几乎都是一样的,只是使用的测试参数不同。

比如:

  • 不输入用户名,输入正确密码
  • 输入比正确用户名后面少一个字符,输入正确密码
  • 输入比正确用户名后面多一个字符,输入正确密码
  • 输入比正确用户名前面少一个字符,输入正确密码
  • 输入比正确用户名前面多一个字符,输入正确密码
  • 输入正确用户名,不输入密码
  • 输入正确用户名,输入比正确密码后面多一个字符

上面每种输入对应一个用例, 聪明的读者应该能想到 可以把整个测试逻辑封装到一个库函数中,如下所示

def login(username,password):
   # 下面写登录流程

但是,测试用例仍然需要定义一个个的类,如下, (假设正确的用户名为 user,密码为 123456)

class c00101:
    name = '登录测试 - c00101' 

    def teststeps(self):
      msg = login('','123456')
      CHECK_POINT(msg, '错误的用户名密码')


class c00102:
    name = '登录测试 - c00102' 

    def teststeps(self):
      msg = login('use','123456')
      CHECK_POINT(msg, '错误的用户名密码')

# 下面还有类似的用例定义      

这样做,当然可以,就是有些麻烦了。

这种情况可以使用 HyRobot用例 的 数据驱动格式,只需如下定义即可

class c_login_x:
    # cases里面每个元组定义每个用例的数据
    # 第一个数据是用例名称, 后面的数据是用例参数
    cases = [
        ('登录 - c00101', '','123456'),
        ('登录 - c00102', 'use','123456'),
        ('登录 - c00103', 'user1','123456'),
    ]

    def teststeps(self, para_index):
        # 取出参数
        username, password = self.cases[para_index][1:]
        # 下面写登录流程

这样,我们就不需要定义那么多的测试用例类了, 而且测试数据也可以集中存放。

视频讲解中的被测系统白月SMS如何安装,看课后练习部分说明

视频讲解中的 测试用例代码如下

from hyrobot.common import  *
from selenium import webdriver
import time

class c_login_x:
    cases = [
        ('登录 - c00101', 'byhy1','888888'),
        ('登录 - c00102', 'byh','888888'),
        ('登录 - c00103', '','888888'),
    ]

    def teststeps(self, para_index):
        # 取出参数
        username, password = self.cases[para_index][1:]
        # 下面写登录流程

        driver = webdriver.Chrome()
        driver.implicitly_wait(10)

        driver.get('http://127.0.0.1/mgr/sign.html')

        driver.find_element_by_id('username').send_keys(username)
        driver.find_element_by_id('password').send_keys(password)
        driver.find_element_by_css_selector('button[type="submit"]').click()

        time.sleep(2)
        alterText = driver.switch_to.alert.text
        print(alterText)
        CHECK_POINT('弹出提示', alterText == '登录失败 : 用户名或者密码错误')


        driver.quit()

初始化、清除、共享数据

原则是:

做的 初始化 操作对环境产生了 什么改变 就应该在 清除 操作里面做什么样的 还原

自己拉的屎,自己擦屁股,不要让别人帮你擦,而且还要擦干净。

黑羽robot的初始化/清除(和robotframework一样)支持 3种方式

  • 单个用例的初始化、清除
  • 整个用例文件的初始化、清除
  • 整个用例目录的初始化、清除

单个用例的初始化、清除

首先看第一种:

单个用例的初始化、清除 是在 用例对应的类里面添加setup、teardown 方法

class c0101:
    name = '管理员首页 - UI-0101'

    # 初始化方法
    def setup(self):
        wd = open_browser()
        mgr_login(wd)

    #清除方法
    def teardown(self):
        wd = get_global_webdriver()
        wd.quit()

    # 测试用例步骤
    def teststeps(self):
        # 获取webdriver对象 对应 已经登录好的浏览器
        wd = get_global_webdriver()

        STEP(1, '获取左侧菜单信息')

然后修改 库文件 webui.py ,如下

def open_browser():

    print('打开浏览器')
    wd = webdriver.Chrome()
    wd.implicitly_wait(5)

    # 使用黑羽robot 全局存储对象 GSTORE
    GSTORE['global_webdriver'] = wd
    return wd

# 获取 全局使用的 webdriver 对象
def get_global_webdriver():
    return GSTORE['global_webdriver']

注意: 我们在创建 WebDriver 对象后,把它存到了 黑羽robot 全局存储对象 GSTORE 中。 方便其他的代码 获取。

黑羽robot执行用例时

  • 先执行 setup 里面的代码
  • 再执行 teststeps 里面的代码
  • 最后再执行 teardown 里面的代码。

而且

如果 setup 执行失败(有 异常), 就不会再执行 teststeps 和 teardown 里面的代码了。

如果 teststeps 执行失败, 仍然会执行 teardown , 确保环境被 清除

用例文件的初始化、清除

点击这里,边看视频讲解,边学习以下内容

精明的读者肯定已经发现,上面这种单个用例的初始化、清除,并没有解决我们前面说的 多个用例共享 数据环境的问题。

这时,我们可以使用 整个用例文件的初始化、清除

整个 用例文件 的初始化、清除 是在 文件中 添加全局函数 suite_setup、suite_teardown

如下所示

from hyrobot.common import *
from lib.webui import  *
from time import sleep

def suite_setup():
    INFO('suite_setup')
    wd = open_browser()
    mgr_login(wd)

def suite_teardown():
    INFO('suite_teardown')
    wd = get_global_webdriver()
    wd.quit()

class c0101:
    # 测试用例名字
    name = '管理员首页 - UI-0101'

    # 测试用例步骤
    def teststeps(self):

        wd = get_global_webdriver()

        STEP(1, '获取左侧菜单信息')

        # 先找到上层节点,缩小查找范围
        sidebarMenu = wd.find_element_by_class_name('sidebar-menu')

        # 再找到内部元素
        elements = sidebarMenu.find_elements_by_tag_name('span')

        menuTitles = []
        for ele in elements:
            INFO(ele.text)
            menuTitles.append(ele.text)


        STEP(2, '检查是否正确')

        CHECK_POINT("侧边栏菜单是否正确",
                    menuTitles[:3] == ['客户', '药品', '订单'])


class c0102:
    name = '管理员首页 - UI-0102'

    # 测试用例步骤
    def teststeps(self):

        wd = get_global_webdriver()


        STEP(1, '点击左侧客户菜单')

        # 先找到上层节点,缩小查找范围
        sidebarMenu = wd.find_element_by_class_name('sidebar-menu')

        # 再找到内部元素
        elements = sidebarMenu.find_elements_by_tag_name('span')

        # 第一个span对应的菜单是 客户,点击它
        elements[0].click()

        STEP(2, '添加客户')

        # 点击添加客户按钮
        wd.find_element_by_class_name('glyphicon-plus').click()

        # form-contorl 对应3个输入框
        inputs = wd.find_element_by_class_name('add-one-area') \
            .find_elements_by_class_name('form-control')

        # 输入客户姓名
        inputs[0].send_keys('南京中医院')
        # 输入联系电话
        inputs[1].send_keys('2551867858')
        # 输入客户描述
        inputs[2].send_keys('江苏省-南京市-秦淮区-汉中路-16栋504')

        # 第1个 btn-xs 就是创建按钮, 点击创建按钮
        wd.find_element_by_class_name('add-one-area') \
            .find_element_by_class_name('btn-xs') \
            .click()

        # 等待1秒
        sleep(1)


        STEP(3, '检查添加信息')

        # 找到 列表最上面的一栏
        item = wd.find_elements_by_class_name('search-result-item')[0]

        fields = item.find_elements_by_tag_name('span')[:6]

        texts = [field.text for field in fields]
        print(texts)

        # 预期内容为
        expected = [
            '客户名:',
            '南京中医院',
            '联系电话:',
            '2551867858',
            '地址:',
            '江苏省-南京市-秦淮区-汉中路-16栋504'
        ]

        CHECK_POINT('客户信息和添加内容一致 ',
                    texts == expected)

如果一个 用例文件 既有 suite_setup、suite_teardown ,用例里面也有 setup、teardown , 执行的顺序如下

image

套件目录的初始化、清除

点击这里,边看视频讲解,边学习以下内容

刚才我们做到了让一个用例文件里面,所有的用例都共享初始化、清除操作。

如果 多个用例文件里面,的用例都需要相同的初始化清除操作怎么办? 比如目录结构

这时,我们可以使用 整个用例文件的初始化、清除

除了登录测试,其他所有的web界面操作都需要 打开浏览器登录,否则也会导致多次打开浏览器。

可以把打开浏览器的操作设置为 web界面操作目录 共同的初始化

把其他放到 登录后操作 目录中, 添加登录后操作的 初始化

那么怎么设置一个目录共同的初始化呢?

就是 在这个目录下面创建名为 __st__.py 的文件。

和套件文件一样,套件目录的 的初始化、清除 也是在 文件中 添加全局函数 suite_setup、suite_teardown。

请大家根据我们的视频 修改用例目录结构,加上 合适的 初始化、清除 代码。

可以点击这里,下载视频中的示例代码

如果 套件目录有 suite_setup、suite_teardown, 用例文件也有 suite_setup、suite_teardown ,用例里面也有 setup、teardown , 执行的顺序如下所示

image

缺省初始化、清除

用例文件、和套件目录 除了 可以使用 suite_setup、suite_teardown 对整个目录进行初始化清除,还支持另外一种初始化清除: 缺省初识化、清除

就是定义 名称为 test_setuptest_teardown 的全局函数。

如果在 用例文件 中定义了 全局函数 test_setup ,如果 该文件中 有用例本身没有初始化 方法, 执行自动化的时候就会对该用例,使用这个 test_setup 初始化

如果在 用例文件 中定义了 全局函数 test_teardown ,如果 该文件中 有用例本身没有清除 方法, 执行自动化的时候就会对该用例,使用这个 test_teardown 清除。

执行自动化测试的时候,往往我们并不需要执行 全部的 测试用例。

比如:冒烟测试,只需要测试冒烟测试的那些用例。 或者调试自己写的某个用例的自动化,就只需要执行那一个用例。

黑羽robot 可以灵活的挑选要执行的测试用例。

黑羽robot是基于 robotframework 的, 挑选用例执行的机制和 robotframework 完全一致

指定关键测试用例

点击这里,边看视频讲解,边学习以下内容

黑羽robot 执行时,可以指定用例是否是 关键(critical) 测试用例。

如果本次测试中有关键测试用例没有通过,整个测试就被视为测试不通过。 即使100个用例中只有1个关键用例没有通过,

反之,所有关键用例都通过,整个测试就视为通过。 即使100个中有99个非关键用例没有通过,只有1个关键通过。

黑羽robot 执行测试时,如果没有命令行参数特别指定,每个测试用例都被视为关键测试用例。

我们可以修改下面的的用例,故意产生错误

class c1401:
    name = '订单管理 - UI-1401'
    tags = 'order1'

    def teststeps(self):
        STEP(1,'添加订单')
        STEP(2,'检查结果')
        # 故意产生错误
        raise Exception()

当我们运行 黑羽robot 发现 有用例不通过, 然后再看Report, 发现测试报告底色是红色的。 表示整个测试是失败的。

因为缺省都是critical, 所以用红色表示测试不通过

我们可以通过命令参数 --critical--noncritical 后面加 标签名称 来指定哪些用例 是 关键用例 或者 非关键用例。

比如:

run --critical first

指定 只有具有 first 标签的用例才是关键用例 其它都不是

run --noncritical first

指定 具有 first 标签的用例是非关键用例,其他用例都是关键用例。

run --critical basic*  --critical important*

指定 具有 以 basic 开头 或者 important开头 的标签 的用例都是关键用例,其他用例都不是关键用例。


如果我们执行时,指定这个用例为非关键用例,如下所示

run --nocritical order1

然后再看Report, 发现测试报告底色是绿色的。因为这个用例都变成非关键用例了,即使失败,也认为测试结果是通过的。

一些特殊参数

  • 清除所有robot用例文件

    使用参数 run.bat --delrf 删除已经存在的 robotframework格式的用例,不执行测试

  • 只转化Python用例为robotframework格式用例

    使用参数 run.bat --torf 只执行转化Python用例为RF用例,不执行转化好的RF测试用例

  • 只运行测试

    使用参数 run.bat --runrf 直接执行已经存在的robotframework用例,不执行转化Python用例为RF用例操作

  • 只汉化测试报告

    使用参数 run.bat --hanrf 只执行把测试报告汉化的工作,不执行转化和测试

调试

点击这里,边看视频讲解,边学习以下内容

黑羽robot运行后,如果发现 程序出现了问题,怎么去 debug 呢?

debug 日志级别

在命令行加上 -L debug 参数,使得日志信息更加详细

run -L debug

如果有错误,会打印详细的错误信息,方便定位。

pycharm断点调试

黑羽robot 运行时,做两件事情

  1. 扫描 Python 格式的测试用例 产生对应的 Robotframework 格式的测试用例
  2. 调用 Robotframework 执行测试用例

要断点调试,必须先 执行命令 run.bat --torf,把Python 格式的测试用例转化为 Robotframework格式的用例,然后再调试

黑羽robot 调用 Robotframework 执行测试用例,其实就是 执行类似如下的命令

python -m robot.run cases

上面意思就是执行robot包里面的run.py文件

既然本质上就是一个python程序,当然我们可以在pycharm中执行,以前设置断点的方法依然可以使用

但是我们需要从pycharm里面运行,就需要配置运行参数,点击配置

image

然后,如下图所示,进行配置。注意下图方框里面要点击箭头,从 Script path 改为 Module name

image

这样设置,执行的时候,就等于执行了下面的命令

cd E:\tmp\autotest_bysms
python.exe  -m robot.run  cases

然后再点击debug的图标,就可以进行断点调试了。


文章作者: 姜楠
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 姜楠 !
  目录