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

作者: oychw | 来源:发表于2018-07-18 05:44 被阅读122次

    Multi-Mechanize简介

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

    主要特性:

    • 支持各种 HTTP methods

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

    • 支持 SSL

    • 自动处理 Cookies

    • 可设置HTTP头

    • 自动处理重定向

    • 支持代理

    • 支持 HTTP 认证

    图片.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导入。

    测试结果参见:

    image.png 图片.png 图片.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书写了。

    可爱的python测试开发库 请在github上点赞,谢谢!
    python中文库文档汇总
    接口自动化性能测试线上培训大纲
    python测试开发自动化测试数据分析人工智能自学每周一练
    [雪峰磁针石博客]python3标准库-中文版

    更多内容请关注 雪峰磁针石:简书

    • 技术支持qq群: 144081101(后期会录制视频存在该群群文件) 591302926 567351477 钉钉免费群:21745728

    • 道家技术-手相手诊看相中医等钉钉群21734177 qq群:391441566 184175668 338228106 看手相、面相、舌相、抽签、体质识别。服务费50元每人次起。请联系钉钉或者微信pythontesting

    下例使用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'
    
    

    参考资料:

    相关文章

      网友评论

        本文标题:[雪峰磁针石博客] multi-mechanize性能测试工具

        本文链接:https://www.haomeiwen.com/subject/bgygpftx.html