zoukankan      html  css  js  c++  java
  • RobotFramework RobotFramework官方demo Quick Start Guide浅析

    RobotFramework官方demo Quick Start Guide浅析

     

    by:授客 QQ:1033553122

     

      博客:http://blog.sina.com.cn/ishouke 

     

    欢迎加入软件性能测试交流QQ群:7156436

     

     

     

    目录

    1、 开发环境 1

    2、 安装robotframework 1

    3、 脚本分析 2

    sut/login.py 2

    Lib/LoginLibrary.py 6

    运行rst配置文件 9

     

    1、 开发环境

    win7 x64

     

    PyCharm 4.0.5

     

    Python 3.3.2

     

    robotframework-master.zip

    下载地址1:https://github.com/robotframework/robotframework

     

    下载地址2:http://pan.baidu.com/s/1dE2nz9Z

     

    QuickStartGuide-master.zip

    下载地址1:https://github.com/robotframework/QuickStartGuide

     

     

    下载地址2:http://pan.baidu.com/s/1gfiMS5l

     (因为官方的demo有些bug,在其基础上做了些修改)

     

    2、 安装robotframework

    下载.zip压缩文件后解压安装

    D:Program Filespython33Libsite-packages>robotframework-master>python setup.py

     

    修改path环境变量,增加指向robot的路径

    D:Program Filespython33Scripts

     

    参考连接:https://github.com/robotframework/robotframework/blob/master/INSTALL.rst

     

    3、 脚本分析

     

    sut/login.py

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-

    from __future__ import  print_function


    import os.path
    import sys
    import tempfile
    import study

    DATABASE_FILE = os.path.join(tempfile.gettempdir(), 'robotframework-quickstart-db.txt')

    class User(object):
        def __init__(self, username, password, status='Inactive'):
            self._validate_password(password)
            self._username =  username
            self._password = password
            self._status = status

        @property
        def username(self):
            return self._username

        @username.setter
        def username(self, username):
            self._username = username

        @property
        def password(self):
            return self._password

        @password.setter
        def password(self, password):
            self._validate_password(password)
            self._password = password

        @property
        def status(self):
            return self._status

        @status.setter
        def status(self, status):
            self._status = status

        def _validate_password(self, password):
            if not (7 <= len(password) <= 12):
                raise ValueError('Password must be 7~12 characters long')
            if not self._validate_password_chars(password):
                raise ValueError('Password must be a combiantion of lowercase and'
                                 'uppercase letters and numbers')


        def _validate_password_chars(self, password):
            has_lower = has_upper = has_number = False
            for char in password:

                if char.islower():
                    has_lower = True
                elif char.isupper():

                    has_upper = True
                elif char.isdigit():

                    has_number = True
                else:

                    return False
            return has_lower and has_upper and has_number


    class UserDataBase(object):
        def __init__(self, db_file=DATABASE_FILE):
            self.users = self._read_users(db_file)
            self.db_file = db_file

        def _read_users(self, path):
            users = {}
            if os.path.isfile(path): #判断所给路径path是否指向一个文件
                with open(path) as file:

                    for row in file.readlines():
                        user = User(*row.rstrip(' ').split(' '))
                        users[user.username] = user
            return users

        def create_user(self, username, password):
            try:
                user = User(username, password)
            except ValueError as err:
                return 'Creating user failed: %s' % err
            self.users[user.username] = user
            return  'SUCCESS'

        def login(self, username, password):

            if self._is_valid_user(username, password):
                self.users[username].status = 'Active'
                return 'Logged In'
            return  'Access Denied'

        def _is_valid_user(self, username, password):

            return (username in self.users and self.users[username].password ==  password)

        def change_password(self, username, old_pwd, new_pwd):
            try:
                if not self._is_valid_user(username, old_pwd):
                    raise ValueError('Access Denied')
                self.users[username].password = new_pwd
            except ValueError as err:
                return  'Changing password faild:%s' % err
            else:
                return  'SUCCESS'

        def save(self):

            with open(self.db_file, 'w') as file:
                for user in self.users.values():
                    file.write('%s %s %s ' % (user.username, user.password, user.status))

        def truncate(self):
            with open(self.db_file, 'w') as file:
                file.truncate()
            return 'SUCCESS'

        def __enter__(self):

            return self

        def __exit__(self, *exec_info):
            self.save()


    def login(username, password):
        with UserDataBase() as db:
            print(db.login(username, password))


    def create_user(username, password):
        with UserDataBase() as db:
            print(db.create_user(username, password))

    def change_password(username, old_pwd, new_pwd):
        with UserDataBase() as db:
            print(db.change_password(username, old_pwd, new_pwd))

    def truncate():
        with UserDataBase() as db:
            print(db.truncate())

    def help():
        print('Usage: %s { create | login | change-password | truncate | help}' % os.path.basename(sys.argv[0]))

    if __name__ ==  '__main__':
        actions = {'create': create_user, 'login': login, 'change-password': change_password, 'truncatefile': truncate, 'help': help}
        try:
            study.testt()
            action = sys.argv[1]
        except IndexError:
            action = 'help'
        args = sys.argv[2:]

        try:
            actions[action](*args)
        except (KeyError, TypeError):
            help()

    运行脚本:

    1)登录用户帐号不存在、密码错误

    E:Projectsstudyproject>python sut/login.py login nobody P4ssw0rd

    Access Denied

     

    2)创建用户账户

    E:Projectsstudyproject>python sut/login.py create fred P4ssw0rd

    SUCCESS

     

    3)用创建的用户登录

    E:Projectsstudyproject>python sut/login.py login fred P4ssw0rd

    Logged In

     

    4)创建用户时,用户密码必须包含7-12字符

    E:Projectsstudyproject>python sut/login.py create fred short

    Creating user failed: Password must be 7~12 characters long

     

    5)创建用户时,用户密码必须包含大小写字母和数字字符

    E:Projectsstudyproject>python sut/login.py create fred invalid

    Creating user failed: Password must be a combiantion of lowercase anduppercase l

    etters and numbers

     

    6)修改用户密码,提供错误的原始密码

    E:Projectsstudyproject>python sut/login.py change-password fred wrong NewP4ss

    Changing password faild:Access Denied

     

    7)修改用户密码,提供正确的原始密码

    E:Projectsstudyproject>python sut/login.py change-password fred P4ssw0rd NewP4ss

    SUCCESS

     

    Lib/LoginLibrary.py

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-

    import  os.path

    import subprocess
    import sys

    class LoginLibrary(object):
        def __init__(self):
            self._sut_path = os.path.join(os.path.dirname(__file__),
                                          '..', 'sut', 'login.py')
            self._status = ''

        def create_user(self, username, password):

            self._run_command('create', username, password)

        def change_password(self, username, old_pwd, new_pwd):
            self._run_command('change-password', username, old_pwd, new_pwd)

        def attempt_to_login_with_credentials(self, username, password):
            self._run_command('login', username, password)

        def login(self, username, password):
            self._run_command('login', username, password)

        def status_should_be(self, expected_status):
            if expected_status != self._status:
                raise AssertionError("Expected status to be '%s' but was '%s'."
                                     % (expected_status, self._status))


        def truncate(self):
            self._run_command('truncatefile')

        def _run_command(self, command, *args):
            command = [sys.executable, self._sut_path, command] + list(args)
            process = subprocess.Popen(command, universal_newlines=True, stdout=subprocess.PIPE,
                                       stderr=subprocess.STDOUT)
            self._status = process.communicate()[0].strip()

     

     

    QuickStart.rst文件

    .. code:: robotframework

        *** Test Cases ***
        User can create an account and log in
            [Tags]    mytag
            Create Valid User    fred    P4ssw0rd
            Attempt to Login with Credentials    fred    P4ssw0rd
            Status Should Be    Logged In

        Invalid password
            [Template]    Creating user with invalid password should fail
            abCD5            ${PWD INVALID LENGTH}
            abCD567890123    ${PWD INVALID LENGTH}
            123DEFG          ${PWD INVALID CONTENT}
            abcd56789        ${PWD INVALID CONTENT}
            AbCdEfGh         ${PWD INVALID CONTENT}
            abCD56+          ${PWD INVALID CONTENT}

        User can change password
            Given A user has a valid account
            When she changes her password
            Then she can log in with the new password
            And she cannot use the old password anymore

        *** Keywords ***
        Create valid user
            [Arguments]    ${username}    ${password}
            Create user    ${username}    ${password}
            Status should be    SUCCESS

        Creating user with invalid password should fail
            [Arguments]    ${password}    ${error}
            Create user    example    ${password}
            Status should be    Creating user failed: ${ERROR}

         A user has a valid account
            Create valid user    ${USERNAME}    ${PASSWORD}

        She changes her password
            Change password    ${USERNAME}    ${PASSWORD}    ${NEW PASSWORD}
            Status should be    SUCCESS

        She can log in with the new password
            Login    ${USERNAME}    ${NEW PASSWORD}

        She cannot use the old password anymore
            Attempt to login with credentials    ${USERNAME}    ${PASSWORD}
            Status should be    Access Denied

        Clear Login Database
            Truncate

        *** Variables ***
        ${USERNAME}               janedoe
        ${PASSWORD}               J4n3D0e
        ${error}                  123456
        ${NEW PASSWORD}           e0D3n4J
        ${DATABASE FILE}          ${TEMPDIR}${/}robotframework-quickstart-db.txt
        ${PWD INVALID LENGTH}     Password must be 7-12 characters long
        ${PWD INVALID CONTENT}    Password must be a combination of lowercase and uppercase letters and numbers
        ${ERROR}                  Creating user failed: Password must be 7-12 characters long
       

        *** Settings ***
        Suite Setup       Clear Login Database
        Test Teardown     Clear Login Database
        Force Tags     quickstart
        Default Tags   example    smoke
        Library           OperatingSystem
        Library           ../Lib/LoginLibrary.py

    __ `Creating test libraries`_

     

     

    运行rst配置文件

    E:Projectsstudyproject>robot QuickStart.rst

     

    robot QuickStart.rst 到运行login.py分析

     

    Demo大致的思路是这样的:

    解析用户关键字 -> 查找函数关键字 -> 函数关键字对应的类库函数 -> 运行关键字(通过特定指令,也可以理解为关键字) -> 找到需要执行的模块函数 -> 在模块函数中进行对象操作,管理

     

    这里_run_command通过Popen来执行执行模块中的函数

     

    个人理解,运行robot QuickStart.rst 时,可能也是构造了一个类库对象,类似如下:

    obj = LoginLibrary(),有对象后,就可以调用方法了:

    obj.create_user('username', 'password')

     

     

    需要注意.rst文件中关键词和类库函数之间的映射关系:关键词中的空格等同类库函数名称中的下划线 _,一个空格可以对应多个下划线,一个下划线似乎可以对应多个关键词单词之间的空格,不分字母大小写。

     

     

    参考连接:

    https://github.com/robotframework/QuickStartGuide/blob/master/QuickStart.rst

     

     

    网盘连接分享:RobotFramework官方demo Quick Start Guide浅析

     

  • 相关阅读:
    memento模式
    observe模式
    state模式
    Trie树的简单介绍和应用
    strategy模式
    全组和问题
    SRM 551 DIV2
    全排列问题
    TSE中关于分词的算法的改写最少切分
    template模式
  • 原文地址:https://www.cnblogs.com/shouke/p/10157603.html
Copyright © 2011-2022 走看看