python模块介绍- multi-mechanize 性能测试工具
python模块介绍- multi-mechanize 性能测试工具
2013-09-13 磁针石
#承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319
#博客:http://blog.csdn.net/oychw
#版权所有,转载刊登请来函联系
# 深圳测试自动化python项目接单群113938272深圳广州软件测试开发 6089740
#深圳湖南人业务户外群 66250781武冈洞口城步新宁乡情群49494279
#参考资料:python手册
Multi-Mechanize 是一个开源的性能和负载测试框架,它并发运行多个 Python 脚本对网站或者服务生成负载(组合事务)。
Multi-Mechanize最常用于web性能和可扩展性(scalability)测试,也适用于任何python可以访问的API。
测试输出报告保存为HTML或JMeter的兼容的XML。主要特性:
- 支持各种 HTTP methods
- 高级超链接和HTML表单支持
- 支持 SSL
- 自动处理 Cookies
- 可设置HTTP头
- 自动处理重定向
- 支持代理
- 支持 HTTP 认证
安装
使用标准的python安装方式。注意,需要安装matplotlib以支持作图,在centos6下面可以这样安装yum -y install python27-matplotlib。这里都以linux(centos)为例。
快速入门:
创建项目:# multimech-newproject my_project
执行项目:# multimech-run my_project
user_groups: 2
threads: 6
[================100%==================] 30s/30s transactions: 119 timers:119 errors: 0
waiting for all requests tofinish...
analyzing results...
transactions: 125
errors: 0
test start: 2013-09-13 11:47:47
test finish: 2013-09-13 11:48:16
created:./my_project/results/results_2013.09.13_11.47.46/results.html
done.
至此,我们已经完成了一个简单的性能测试。
查看性能测试结果:./my_project/results/results_2013.09.13_11.47.46/results.html
Performance Results Report
Summary
transactions: 125
errors: 0
run time: 30 secs
rampup: 0 secs
test start: 2013-09-1311:47:47
test finish: 2013-09-1311:48:16
time-series interval: 10secs
workload configuration:
|
group name |
threads |
script name |
|
user_group-1 |
v_user.py |
|
|
user_group-2 |
v_user.py |
All Transactions
Transaction Response Summary (secs)
|
count |
min |
avg |
80pct |
90pct |
95pct |
max |
stdev |
|
1.021 |
1.499 |
1.796 |
1.890 |
1.972 |
2.002 |
0.282 |
Interval Details (secs)
|
interval |
count |
rate |
min |
avg |
80pct |
90pct |
95pct |
max |
stdev |
|
4.30 |
1.021 |
1.462 |
1.688 |
1.841 |
1.897 |
2.002 |
0.263 |
||
|
3.90 |
1.026 |
1.543 |
1.830 |
1.934 |
1.976 |
1.986 |
0.290 |
||
|
3.70 |
1.025 |
1.495 |
1.806 |
1.964 |
1.985 |
1.988 |
0.295 |
Graphs
Response Time: 10 sectime-series
Response Time: raw data (allpoints)
Throughput: 5 sec time-series
Custom Timer: Example_Timer
Timer Summary (secs)
|
count |
min |
avg |
80pct |
90pct |
95pct |
max |
stdev |
|
1.020 |
1.497 |
1.794 |
1.889 |
1.970 |
2.000 |
0.281 |
Interval Details (secs)
|
interval |
count |
rate |
min |
avg |
80pct |
90pct |
95pct |
max |
stdev |
|
4.30 |
1.020 |
1.461 |
1.686 |
1.839 |
1.895 |
2.000 |
0.262 |
||
|
3.90 |
1.025 |
1.542 |
1.828 |
1.932 |
1.975 |
1.984 |
0.289 |
||
|
3.70 |
1.024 |
1.493 |
1.804 |
1.962 |
1.983 |
1.986 |
0.295 |
Graphs
Response Time: 10 sectime-series
Response Time: raw data (allpoints)
Throughput: 10 sec time-series
目录结构:
每个测试项目包含以下内容:
config.cfg的配置文件。用于设定测试选项。
test_scripts/虚拟用户脚本的目录。在这里添加您的测试脚本。
results/:结果存储目录。对于每个测试都声称一个时间戳目录,里面包含结果的报告。
multimech-newproject,默认生成一个随机数的脚本。脚本如下:
# cat v_user.py
import random
import time
class Transaction(object):
def__init__(self):
pass
defrun(self):
r= random.uniform(1, 2)
time.sleep(r)
self.custom_timers['Example_Timer'] = r
if __name__ == '__main__':
trans= Transaction()
trans.run()
print trans.custom_timers
配置参数的含义如下:
- run_time: duration of test (seconds)
- rampup: duration of user rampup (seconds)
- results_ts_interval: time series interval for results analysis (seconds)
- progress_bar: turn on/off console progress bar during test run
- console_logging: turn on/off logging to stdout
- xml_report: turn on/off xml/jtl report
- results_database: database connection string (optional)
- post_run_script: hook to call a script at test completion (optional)
特别提下 rampup表示多长时间内加载完所有用户。详细的配置参见:http://testutils.org/multi-mechanize/configfile.html
脚本书写:
用Python书写,
测试脚本模拟虚拟用户对网站/服务/ API的请求,
脚本定义了用户事务
更多内容参见脚本手册:http://testutils.org/multi-mechanize/scripts.html#scripts-label
每个脚本必须实现一个Transaction()类。这个类必须实现一个run()方法。基本的测试脚本结构如下:
class Transaction(object):
def run(self):
# do something here
return
运行期间,Transaction()实例化一次,run()方法则反复调用:
class Transaction(object):
def __init__(self):
# do per-user user setup here
#this gets called once on user creation
return
def run(self):
# do user actions here
# this gets called repeatedly
return
从结构上看,如果每次run如果需要setup和teardown,时间也会计算在run里面,会显得事务处理的时间更长。这个就需要使用定时器来精确计时。
另外脚本建议先调试之后在运行,因为Multi-Mechanize有可能报错不够精准。可以这样运行:# python v_suds.py。v_suds.py是你实际使用的脚本名。另外suds这个库好像实现时性能一般,并发200时,客户端cpu占用率经常会100%,为此web service如果要上大量用户的话,建议用其他库替代,比如soapPy。
下例使用mechanize进行web测试。
class Transaction(object):
def __init__(self):
pass
def run(self):
br = mechanize.Browser()
br.set_handle_robots(False)
resp =br.open('http://192.168.4.13/env.htm')
assert (resp.code == 200), 'BadResponse: HTTP %s' % resp.codes
assert ('service name' inresp.get_data())
下面用httplib库重写脚本,并增加定时器。通过定时器,可以分析各个步骤的耗时。
import httplib
import time
class Transaction(object):
defrun(self):
conn = httplib.HTTPConnection('192.168.4.13')
start = time.time()
conn.request('GET', '/env.htm')
request_time = time.time()
resp = conn.getresponse()
response_time = time.time()
conn.close()
transfer_time = time.time()
self.custom_timers['request sent'] = request_time - start
self.custom_timers['response received'] = response_time - start
self.custom_timers['content transferred'] = transfer_time - start
assert (resp.status == 200), 'Bad Response: HTTP %s' % resp.status
if __name__ == '__main__':
trans= Transaction()
trans.run()
fortimer in ('request sent', 'response received', 'content transferred'):
print '%s: %.5f secs' % (timer, trans.custom_timers[timer])
http://testutils.org/multi-mechanize/scripts.html#scripts-label还有更多的实例:
importmechanize
importtime
classTransaction(object):
def__init__(self):
pass
defrun(self):
# create a Browserinstance
br = mechanize.Browser()
# don't bother withrobots.txt
br.set_handle_robots(False)
# add a customheader so wikipedia allows our requests
br.addheaders = [('User-agent', 'Mozilla/5.0Compatible')]
# start the timer
start_timer= time.time()
# submit therequest
resp = br.open('http://www.wikipedia.org/')
resp.read()
# stop the timer
latency = time.time() - start_timer
# store the customtimer
self.custom_timers['Load_Front_Page'] = latency
# verify responsesare valid
), 'Bad Response: HTTP%s'% resp.code
assert ('Wikipedia, thefree encyclopedia'in resp.get_data())
# think-time
)
# select first(zero-based) form on page
)
# set form field
br.form['search'] ='foo'
# start the timer
start_timer= time.time()
# submit the form
resp = br.submit()
resp.read()
# stop the timer
latency = time.time() - start_timer
# store the customtimer
self.custom_timers['Search'] = latency
# verify responsesare valid
), 'Bad Response: HTTP%s'% resp.code
assert ('foobar'in resp.get_data()), 'Text AssertionFailed'
# think-time
)
importurllib2
importtime
classTransaction(object):
defrun(self):
start_timer= time.time()
resp = urllib2.urlopen('http://www.example.com/')
content = resp.read()
latency = time.time() - start_timer
self.custom_timers['Example_Homepage'] = latency
), 'Bad Response: HTTP%s'% resp.code
assert ('Example Web Page'in content), 'Text AssertionFailed'
importurllib2
importtime
classTransaction(object):
def__init__(self):
self.custom_timers = {}
withopen('soap.xml') as f:
self.soap_body = f.read()
defrun(self):
req = urllib2.Request(url='http://www.foo.com/service', data=self.soap_body)
req.add_header('Content-Type', 'application/soap+xml')
req.add_header('SOAPAction', 'http://www.foo.com/action')
start_timer= time.time()
resp = urllib2.urlopen(req)
content = resp.read()
latency = time.time() - start_timer
self.custom_timers['Example_SOAP_Msg'] = latency
), 'Bad Response: HTTP%s'% resp.code
assert ('Example SOAPResponse'in content), 'Text AssertionFailed'
importhttplib
importurllib
importtime
classTransaction(object):
def__init__(self):
self.custom_timers = {}
defrun(self):
post_body=urllib.urlencode({
'USERNAME': 'corey',
'PASSWORD': 'secret',})
headers = {'Content-type': 'application/x-www-form-urlencoded'}
start_timer= time.time()
conn = httplib.HTTPConnection('www.example.com')
conn.request('POST', '/login.cgi', post_body, headers)
resp = conn.getresponse()
content = resp.read()
latency = time.time() - start_timer
self.custom_timers['LOGIN'] = latency
), 'Bad Response: HTTP%s'% resp.status
assert ('Example Web Page'in content), 'Text AssertionFailed'
参考资料:
http://testutils.org/multi-mechanize/
python模块介绍- multi-mechanize 性能测试工具的更多相关文章
- python模块介绍-locustio:性能测试工具locustio
转自:http://automationtesting.sinaapp.com/blog/m_locustio_doc python测试文章 http://weibo.com/cizhenshi?is ...
- python模块介绍- HTMLParser 简单的HTML和XHTML解析器
python模块介绍- HTMLParser 简单的HTML和XHTML解析器 2013-09-11 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq ...
- python模块介绍- xlwt 创建xls文件(excel)
python模块介绍- xlwt 创建xls文件(excel) 2013-06-24磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 ...
- python模块介绍- binascii 二进制和ASCII转换
python模块介绍-binascii二进制和ASCII转换 目录 项目简介 简介: Uu编码 Binhex编码 Base64编码 QP码 CRC校验和 二进制转换 其他实例 项目简介 Python中 ...
- 将Python模块转变为命令行工具
问:如何输入命令行就能执行python代码呢? 答:要将python模块转变为命令行工具只用在 setup.py 文件中添加参数entry_points 例如: entry_points={ 'con ...
- python成长之路【第十八篇】:python模块介绍、模块导入和重载
一.模块和命名空间 一般来说,Python程序往往由多个模块文件构成,通过import语句连接在一起.每个模块文件是一个独立完备的变量包,即一个命名空间.一个模块文件不能看到其他文件定义的变量名,除非 ...
- python模块介绍二。
全局变量 全局变量 python在一个.py文件内部自动添加了一些全局变量 print(vars()) #查看当前的全局变量 执行结果: {'__package__': None, '__loader ...
- python模块介绍- SocketServer 网络服务框架
来源:https://my.oschina.net/u/1433482/blog/190612 摘要: SocketServer简化了网络服务器的编写.它有4个类:TCPServer,UDPServe ...
- Python—模块介绍
什么是模块? 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码 ...
随机推荐
- 在TreeWidget中增加右键菜单功能 以及TreeWidget的基本用法
TreeWidget 与 TreeView 中实现右键菜单稍有不同, TreeView 中是靠信号与槽 connect(ui->treeView,SIGNAL(customContextMenu ...
- C#实现阻止关闭显示器和系统待机
原文http://www.cnblogs.com/TianFang/archive/2012/10/12/2721883.html 最近写了一个下载程序,发现有一个问题:挂机下载的时候,下载任务会因为 ...
- cocos2d-x中的导演、场景、层和精灵
场景(Scenes) 场景在cocos2d-x中是CCScene类实现的,是应用程序流中独立的一部分.一个cocos2dx应用程序可以有许多场景,但是在某一时刻,只有一个场景在运行. 比如,你有一个游 ...
- 100% width CSS 在 iPad / iPhone Safari 背景被截断 / 显示不全
Tips: 调试 iPad 或 iPhone 可在设置中启动调试模式,在 Mac 中的 Safari 浏览器 同样开启开发者模式后,进行联机调试.功能彪悍. 最近在做一个页面时,发现在 iPad 的 ...
- c 按输入的字母来输出对应效果
输入一个大写字母,如 F,输出 比如: 输入:F 输出: F EFE DEFED CDEFEDC BCDEFEDCB ABCDEFEDCBA #include<stdio.h> int m ...
- MemberShip使用大全
比较全面的membership 使用过程 http://www.cnblogs.com/xlb2000/archive/2010/07/31/1788120.html Membership中创建的数据 ...
- 建立&修改视图
一.建立视图 IF OBJECT_ID('Sales.OrderTotalsByYear', 'V') IS NOT NULL DROP VIEW Sales.OrderTotalsByYear; G ...
- [译]Stairway to Integration Services Level 6 - SSIS 工作流管理基础
简介 在之前的章节中,我们学习了增量载入数据. 本文中.我们通过优先约束(Precedence Constraints)来管理SSIS的工作流. 添加一个SSIS包 图 1 将新建的Package1. ...
- Eclipse安装反编译插件JD(Java Decompiler)
JD安装说明:*****Eclipse 插件安装*****1. 在网上搜索并下载jdeclipse_update_site.zip2. Eclipse -> Install New Softwa ...
- ThinkPHP第五天(提交类型判定常量IS_POST等,错误页面种类,Model实例化方式,模板中使用函数,foreach循环,模板中.语法配置)
1.IS_GET.IS_POST.IS_PUT.IS_DELETE.IS_AJAX常量,方便快捷实现各个判断. 在Action类中还可以使用$this->isPost()等进行判断. 2.错误页 ...