RobotFramework自动化测试规范

一 RobotFramework框架特点

1 框架特点

RobotFramework框架是一个关键字驱动的自动化测试框架,有着鲜明的分层结构,如下图所示:


2 自动化测试工程结构组织

RobotFramework简介.png

二 RobotFramework自动化测试规范

1. Library层

1.1 Library层语言编码规范

Library由编程语言实现,目前使用最多的是Python和Java,所以遵循对应编程语言的规范即可,例如Python遵循PEP8规范即可,调整Python脚本的编码风格有众多的工具/插件可以完成,例如Pycharm中可以通过快捷键[Ctrl+Alt+L]来一键格式化代码,或者pylint、pep8工具来进行代码检查和调整。

1.2 Library本身应该良好的注释

对一个Library、Class均应该有注释说明,说明该Library的主要功能和用法,初始化参数等等附加信息。

import xxx
import yyy
from robot.api import logger


class MyLibrary(object):
    
    """该库主实现以下关键字:
    HTTP相关事务类型的处理。
    导入方法:
    Library    MyLibrary
    Library    MyLibrary    host=10.0.0.61    username=robotuser    password=allsense@123
    Library    MyLibrary    host=10.0.0.61    password=123456
    """
    
    def __init__(self, host='10.0.0.64', username='admin', password='allsmart@123'):
        self.host = host
        self.password = password
    
    ...        

1.3 Library中关键字应该有良好的定义与注释

关键字是一些定义在库中的函数,函数名称应当明了说明该关键字的作用,命名规范符合对应编程语言的命名规范即可,在Python中,函数名称只包含小写,用下划线连接。

关键字自身用法说明应该包含以下部分:

  • 参数:说明该关键字所需的参数、参数类型以及默认值等信息;

  • 返回值:返回数据的类型、含义以及可能返回的不同结果;

如下示例:


def read_excel(file_name, sheet_index=0, header=1):
    """读取Excel文件.\n
    file_path: Excel文件路径;\n
    sheet_index: 需要读取的sheet的序号,从0开始.\n
    header: 表格的标题栏,如果存在合并行(单元格),标题栏占了几行,那么header等于几。\n

    返回一个列表,列表中的元素是每一行各个单元格的值顺序形成的列表。\n
    
    Example:\n

    | ${excel_content}=  |  Read Excel  |  E:\\test.xlsx  | sheet 0 |  ${0}  |

    """
    
    work_book = xlrd.open_workbook(file_name)

    try:
        work_sheet = work_book.sheet_by_index(sheet_index)
    except:
        raise ValueError("No such sheet in this workbook.")
    else:
        content = list()
        row_num = work_sheet.nrows
        for row in range(header, row_num):
            row_value = work_sheet.row_values(row)
            content.append(row_value)
        return content

另外,关键字函数(方法)的参数不宜过多,并且应该考虑兼容性(采用默认参数)与易用性(参数个数尽量少,参数为常见的数据类型。)

1.4 Library中使用keyword装饰器

使用keyword装饰器装饰一个关键字有如下好处:

  • 明了,让人一眼就知道这是一个关键字(因为库中出关键字外还可能含有私有方法);
  • 可以给关键字起别名,不必与函数的名称一样,个性化关键字的名字;
  • 关键字为了说明功能可能会很长,但是定义的函数(方法)名称就不需要那么长;

举例:

下面定义的关键字中,该关键字的名字变为了“Get Book ISBN With Book Name”, 而不必与定义的函数的名称相同。

from robot.api.deco import keyword


@keyword(name="Get Book ISBN With Book Name")
def get_isbn(bookname):
    """一些注释
    """

    do sth;

说明:RobotFramework框架会自动对定义的关键字做出调整。

  • 自动将函数(方法)名称进行Capitalized(首字母大写)转换,如果不适用keyword装饰,那么自动转换后的关键字为“Get Isbn”, 而 ISBN是一个缩略词,应该完全大写,所以要实现关键字的个性化定义,可以使用keyword装饰。
  • 函数名中的下划线“_”自动转化为一个英文模式下的空格,上例中的关键字自动转化后为“Get Isbn”。

1.5 自行定义的关键字应该有完善的日志记录

内置关键字都有完整的日志记录,有利于分析测试结果以及过程调试,而自己定义的关键字,如果不加日志打印,如果用例中,在该关键字内部出错,因为缺乏错误信息,会变难以调试,所以应当对自己定义的关键字加上必要的日志打印。

RobotFramework已经定义好了日志对象,可以按照以下方式导入:

from robot.api import logger

logger有如下的几种级别,从低到高(日志的重要程度):

  • trace
  • debug
  • info
  • warn
  • error

示例:

    def current_page_should_contain_text(self, *text, period=0.5):
        """判断当前页面是否存在预期的文本,可以给定多个文本字符串。\n
        只要在制定的时间段(time_out)内,其中一个字符串被找到,那么正常结束退出。\n
        如果在指定的时间段(time_out)内,所有字符串都没有找到,那么抛出断言异常。\n

        :param text: 需要判断的字符串,可以为多个字符串\n
        :param period: 没两次判断之间的等待间隔\n
        :return: None\n
        """
        exit_flag = False
        for count in range(0, int(self.time_out / period) + 1):

            for text_ in text:
                try:
                    assert text_ in str(self.driver.page_source)
                except:
                    continue
                else:
                    logger.info("{text} is on page as expected.".format(text=text_))
                    exit_flag = True
                    break
            if exit_flag:
                break
            else:
                if count >= int(self.time_out / period):
                    raise TimeoutError("{text} is not on page after {time_out} seconds waiting.".format(
                        text=text,
                        time_out=self.time_out
                    )
                    )
                else:
                    time.sleep(0.5)

2 Resource层

Resource层主要包含两类资源:变量和高级关键字(由已有关键字进行堆叠封装)。

2.1 Resource文件中变量的定义规范

对于变量全部采用大写形式:

如:

*** Variables ***
${SERVER}         localhost:7272
${BROWSER}        Firefox
${DELAY}          0
${VALID USER}     demo
${VALID PASSWORD}    mode
${LOGIN URL}      http://${SERVER}/
${WELCOME URL}    http://${SERVER}/welcome.html
${ERROR URL}      http://${SERVER}/error.html

2.2 Resource文件中关键字的定义规范

  • 关键字之间空一行;
  • 关键字封装不要太复杂,一个高级关键字尽量不要超过10行;
  • 关键字使用Capitalized形式;
  • 关键字参数应该表明其意义;
*** Keywords ***
Open Browser To Login Page
    [Documentation]    打开浏览器进入登录页面
    Open Browser    ${LOGIN URL}    ${BROWSER}
    Maximize Browser Window
    Set Selenium Speed    ${DELAY}
    Login Page Should Be Open

Login Page Should Be Open
    Title Should Be    Login Page

Go To Login Page
    Go To    ${LOGIN URL}
    Login Page Should Be Open

Input Username
    [Arguments]    ${username}
    Input Text    username_field    ${username}

Input Password
    [Arguments]    ${password}
    Input Text    password_field    ${password}

Submit Credentials
    Click Button    login_button

Welcome Page Should Be Open
    Location Should Be    ${WELCOME URL}
    Title Should Be    Welcome Page

3 TestSuite层(目录套件)

目录套件其实是一个目录,可以包含文件套件,以及其他可能的资源文件。

目录套件中包含一个__init__.robot标识这是一个目录型套件。

目录套件可以集中对该套件进行setUptearDown

目录套件中只包含变量高级关键字

4 TestSuite层(文件套件)

文件套件包含如下四部分

  • *** Settings *** : 引用的库以及资源文件
  • *** Variables *** : 变量,可有可无,除非有只在该套件中使用的变量,且不需要经常变更的变量
  • *** Keyword *** : 该测试套件范围内的关键字
  • *** Test Cases *** : 测试用例部分

文件测试套件尽量遵循以下规则:

  • 尽量不在其中定义变量,除非该变量只在本套件中使用
  • 尽量不在其中定义关键字,除非该关键字只在本套件中多次使用
  • 各部分之间空一行
  • 用例与用例之间空一行
  • 套件内定义自己的setUptearDown
  • 所有robot关键字均采用Capitalized(首字母大写)形式书写
  • 所有robot关键字与关键字、参数,参数与参数之间均间隔四个英文空格

4.1 测试用例名称应该一目了然

  • 测试用例的名称应该一目了然,知道该测试用例所针对的测试点
  • 测试名称加上顺序编号,可以一目知道该测试套件下面有多少条用例,也便于自行解析用例时的排序
  • 可以自行拼接需要的信息,如用例编号,以便于与用例仓库匹配

良好的用例名称示例:

*** Test Cases ***
    001-使用错误的用户名和密码登录应该失败-[用例编号]
        ...
    002-只有系统超级管理员用户可以成功删除其他用户
        ...
    003-云后台管理用户可以成功添加商户
        ...

4.2 必要时添加用例文档

用例名称应当进尽可能全面精准地表达该用例的作用,以至于都不需要看任何其他信息就可以了解测试用例。但是某些特殊的测试场景下,可能需要特别的注释与说明,这时候给测试用例添加一些业务性的说明变得必要。

如:

*** Test Cases ***
    001-正在处理中的工单不能被删除
        [Documentation]    业务逻辑blabla...
        ....

4.3 测试用例必须包含Tag字段

通过Tag字段可以控制测试用例的执行策略,所以每一条用例都必须包含Tag字段。

Tag字段应该是一个可以枚举的值,在开展初期定下来,所有用例按照该标准打上标签(Tag)。

如:

*** Test Cases ***
    001-使用错误的用户名和密码登录应该失败-[用例编号]
        [Tags]    功能    Level 1    
        ...
    002-只有系统超级管理员用户可以成功删除其他用户
        [Tags]    性能    Level 2 
        ...
    003-云后台管理用户可以成功添加商户
        [Tags]    Web安全    Level 1 
        ...

4.4 测试用例中的关键字统一写为Capitalized形式

关键字按照robot的推荐写法书写,不要写为小写或者大小写混合的形式,形式上保持统一

如:

009-部署bi-engine
    [Tags]    初始化    关键
    Comment    bi-engine不咋更新,手动更新,无需每次都运行。
    Comment    bi-engine由骆总单独发布,不在jenkins统一发布平台中
    Open Connection    ${BI_ENGINE_SERVER}
    Login    ${BI_ENGINE_SERVER_SYS_USER}    ${BI_ENGINE_SERVER_SYS_PASS}
    Execute Command    mkdir ${BI_ENGINE_LOCAL_PATH}       
    Put File    ${BI_ENGINE_PACK_PATH}     ${BI_ENGINE_LOCAL_PATH}
    ${dir_path}    ${file_name}=    Split Path    ${BI_ENGINE_PACK_PATH}    
    Execute Command    unzip -o ${BI_ENGINE_LOCAL_PATH}/${file_name} -d ${BI_ENGINE_LOCAL_PATH} 
    Close Connection

4.5 用例中添加必要的注释

用例中添加必要的注释可以使后期维护变得容易。

010-创建初始化数据库
    [Documentation]    ...
    [Tags]    ...
    [setUp]    Create User
    ...
    Comment    给用户分配权限
    ...
    Comment    执行操作
    ...
    [tearDown]    Delete User

4.6 用例中注释推荐采用Comment关键字

用例中注释推荐采用Comment关键字,不推荐使用#号来标记注释内容;

也不推荐Comment#混用。

4.7 不要用中文定义关键字

中文定义关键字更易于阅读和理解,但是在很多的用例编写环境中,中文关键字不支持自动联想和自动补全,并且不容易记忆,使用时容易出错。

[email protected]

2018年12月8日

你可能感兴趣的:(RobotFramework自动化测试规范)