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 Files\python33\Lib\site-packages>robotframework-master>python setup.py
修改path环境变量,增加指向robot的路径
D:\Program Files\python33\Scripts
参考连接: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('\r\n').split('\t'))
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\t%s\t%s\n' % (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:\Projects\studyproject>python sut/login.py login nobody P4ssw0rd
Access Denied
2)创建用户账户
E:\Projects\studyproject>python sut/login.py create fred P4ssw0rd
SUCCESS
3)用创建的用户登录
E:\Projects\studyproject>python sut/login.py login fred P4ssw0rd
Logged In
4)创建用户时,用户密码必须包含7-12字符
E:\Projects\studyproject>python sut/login.py create fred short
Creating user failed: Password must be 7~12 characters long
5)创建用户时,用户密码必须包含大小写字母和数字字符
E:\Projects\studyproject>python sut/login.py create fred invalid
Creating user failed: Password must be a combiantion of lowercase anduppercase l
etters and numbers
6)修改用户密码,提供错误的原始密码
E:\Projects\studyproject>python sut/login.py change-password fred wrong NewP4ss
Changing password faild:Access Denied
7)修改用户密码,提供正确的原始密码
E:\Projects\studyproject>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:\Projects\studyproject>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浅析
RobotFramework RobotFramework官方demo Quick Start Guide浅析的更多相关文章
- RobotFramework 官方demo Quick Start Guide rst配置文件分析
RobotFramework官方demo Quick Start Guide rst配置文件分析 by:授客 QQ:1033553122 博客:http://blog.sina.com.c ...
- Qt5官方demo分析集11——Qt Quick Particles Examples - Affectors
在这个系列中的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集10--Qt ...
- Qt5官方demo解析集13——Qt Quick Particles Examples - Image Particles
本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文 Qt5官方demo解析集12--Qt Quic ...
- Qt5官方demo分析集10——Qt Quick Particles Examples - Emitters
此系列的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 前段时间去听了Qt在北京的开发人员大会,感觉QML ...
- RF《Quick Start Guide》操作总结
这篇文章之所以会给整理出来,是因为学了一个季度的RF后,再去看官网的这个文档,感触破多,最大的感触还是觉得自己走了不少弯路,还有些是学习方法上的弯路.在未查看这类官网文档之前,更多的是看其他各种人的博 ...
- SMJobBless官方Demo笔记
SMJobBless是苹果官方提供的用于"MacOS app获取root权限"的demo. 具体思路 使用Security.framework和ServiceManagement. ...
- 订餐系统之微信支付,踩了官方demo的坑
最近一个项目要增加微信支付的功能,想来这个东西出来这么久了,按微信提供的应该可以很快搞定的,结果提供的demo( JS API网页支付)中各种坑,咨询他们的客服,态度倒是非常好,就是解决不了问 ...
- SlickUpload Quick Start Guide
Quick Start Guide The SlickUpload quick start demonstrates how to install SlickUpload in a new or ex ...
- Dubbo系列(3)_官方Demo说明
一.本文目的 通过Dubbo的官方Demo介绍,学会搭建一个简单的Dubbo程序,包括服务端.客户端.接口等. Demo地址:https://github.com/alibaba/dubbo/ ...
随机推荐
- 【app】adb连接问题整理
如果使用adb devices进行检测,发现没有任何设备信息,我们就需要检查是否有手机/模拟器连接上 如果是手机进行连接,windows右下角有出来如下提示的话,需要检查你的手机驱动是否有安装好 如果 ...
- python(leetcode)-14最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...
- 解决 .NET Core 在 Linux 下的时区问题
环境 # dotnet --info .NET Core SDK (reflecting any global.json): Version: Commit: 8a7ff6789d Runtime E ...
- XMPP大杂烩
XMPP大杂烩 对XMPP的理解 XMPP是基于XML的即时通讯协议.对即时通讯场景进行了高度抽象,比如用订阅对方的上下线状态表示好友.提供了文本通讯.用户上下线通知.联系人管理.群组聊天等功能,还可 ...
- SpringContextHolder 静态持有SpringContext的引用
import java.util.Map; import org.springframework.context.ApplicationContext; import org.springframew ...
- 【原创】深入理解c++的右值引用
0 左值和右值 一个左值表达式代表的是对象本身,而右值表达式代表的是对象的值:变量也是左值. 1 右值引用作用 为了支持移动操作(包括移动构造函数和移动赋值函数),C++才引入了一种新的引 ...
- 编码(2)从字节理解Unicode(UTF8/UTF16)
https://www.cnblogs.com/zizifn/p/4716712.html 从字节理解Unicode(UTF8/UTF16) 如果你不知道或者不了解什么是Unicode/UTF8/UT ...
- 监控报I/O问题,怎么办?
Linux系统出现了性能问题,一般我们可以通过top.iostat.free.vmstat等命令来查看初步定位问题.其中iostat可以给我们提供丰富的IO状态数据. 一.查询命令基本使用 1.命令介 ...
- jmeter 新手使用教程
jmeter是一款很好的接口和压力测试工具,下载就不说了,去jmeter官网下载即可. 解压缩到本地,然后进入bin文件夹点击jmeter.bat 一.新建一个线程组 线程组内各项配置的含义 二.添加 ...
- 【Vue.js】vue项目目录作用
1. build文件夹:打包配置的文件夹 1.1 webpack.base.conf.js :打包的核心配置 1.2 build.js:构建生产版本,项目开发完成之后,通过build.js打包(加 ...