您现在的位置是:首页 > 文章详情

[雪峰磁针石博客]multi-mechanize性能测试工具

日期:2018-08-15点击:556

Multi-Mechanize简介

Multi-Mechanize 是一个开源的性能和负载测试框架,它并发运行多个 Python 脚本对网站或者服务生成负载(组合事务)。测试输出报告保存为HTML或JMeter的兼容的XML。Multi-Mechanize最常用于web性能 和可扩展性(scalability)测试,也适用于任何python可以访问的API。尤其适合后台性能测试。稍微懂点编程的话,这个工具会远强过商业 的性能测试工具。

主要特性:

  • 支持各种 HTTP methods

  • 高级超链接和HTML表单支持

  • 支持 SSL

  • 自动处理 Cookies

  • 可设置HTTP头

  • 自动处理重定向

  • 支持代理

  • 支持 HTTP 认证

600
图片.png

安装

使 用标准的python安装方式。注意,需要安装matplotlib以支持作图,在centos6下面可以这样安装yum -y install python27-matplotlib。multi-mechanize采用标准的python安装方式pip install multi-mechanize或者easy_install multi-mechanize这里都以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 to finish... 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. 

如果有出现figure没有定义,请在相关文件的头部从matplotlib导入。

测试结果参见:

700
image.png
700
图片.png
700
图片.png

目录结构

每个测试项目包含以下内容:

  • config.cfg的配置文件。用于设定测试选项。

  • test_scripts/虚拟用户脚本的目录。在这里添加您的测试脚本。

  • results/:结果存储目录。对于每个测试都声称一个时间戳目录,里面包含结果的报告。

multimech-newproject,默认生成一个随机数的脚本。脚本v_user.py如下:

 import randomimport timeclass Transaction(object): def __init__(self): pass def run(self): r = random.uniform(1, 2) time.sleep(r) self.custom_timers['Example_Timer'] = rif __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 是否输出到stdout

  • xml_report: turn on/off xml/jtl report 是否生成xml报告。

  • results_database: database connection string (optional) 保存结果的数据库连接字符串(可选)

  • post_run_script: hook to call a script at test completion (optional) 调用的善后脚本(可选)

更多介绍参见: 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。进一步提升效率可以试用python的ctypes模块,或者cython(性能接近c语言)。不过Multi-Mechanize的多进程是基于python的,实在对性能有相当高的要求,就只能全部用c书写了。

下例使用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), 'Bad Response: HTTP %s' % resp.codes assert ('service name' in resp.get_data()) 

下面用httplib库重写脚本,并增加定时器。通过定时器,可以分析各个步骤的耗时。

import httplib import time class Transaction(object): def run(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() for timer 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 还有更多的实例。

 import mechanize import time class Transaction(object): def __init__(self): pass def run(self): # create a Browser instance br = mechanize.Browser() # don't bother with robots.txt br.set_handle_robots(False) # add a custom header so wikipedia allows our requests br.addheaders = [('User-agent', 'Mozilla/5.0 Compatible')] # start the timer start_timer = time.time() # submit the request resp = br.open('http://www.wikipedia.org/') resp.read() # stop the timer latency = time.time() - start_timer # store the custom timer self.custom_timers['Load_Front_Page'] = latency # verify responses are valid assert (resp.code == 200), 'Bad Response: HTTP %s' % resp.code assert ('Wikipedia, the free encyclopedia' in resp.get_data()) # think-time time.sleep(2) # select first (zero-based) form on page br.select_form(nr=0) # 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 custom timer self.custom_timers['Search'] = latency # verify responses are valid assert (resp.code == 200), 'Bad Response: HTTP %s' % resp.code assert ('foobar' in resp.get_data()), 'Text Assertion Failed' # think-time time.sleep(2) 
import urllib2 import time class Transaction(object): def run(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 assert (resp.code == 200), 'Bad Response: HTTP %s' % resp.code assert ('Example Web Page' in content), 'Text Assertion Failed' 
import urllib2 import time class Transaction(object): def __init__(self): self.custom_timers = {} with open('soap.xml') as f: self.soap_body = f.read() def run(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 assert (resp.code == 200), 'Bad Response: HTTP %s' % resp.code assert ('Example SOAP Response' in content), 'Text Assertion Failed' 

参考资料

原文链接:https://yq.aliyun.com/articles/625860
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章