zoukankan      html  css  js  c++  java
  • 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

    3

    v_user.py

    user_group-2

    3

    v_user.py

    All Transactions

    Transaction Response Summary (secs)

    count

    min

    avg

    80pct

    90pct

    95pct

    max

    stdev

    125

    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

    1

    43

    4.30

    1.021

    1.462

    1.688

    1.841

    1.897

    2.002

    0.263

    2

    39

    3.90

    1.026

    1.543

    1.830

    1.934

    1.976

    1.986

    0.290

    3

    37

    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

    119

    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

    1

    43

    4.30

    1.020

    1.461

    1.686

    1.839

    1.895

    2.000

    0.262

    2

    39

    3.90

    1.025

    1.542

    1.828

    1.932

    1.975

    1.984

    0.289

    3

    37

    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

            assert (resp.code ==200), 'Bad Response: HTTP%s'% resp.code

            assert ('Wikipedia, thefree 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 customtimer

            self.custom_timers['Search'] = latency

     

            # verify responsesare valid

            assert (resp.code ==200), 'Bad Response: HTTP%s'% resp.code

            assert ('foobar'in resp.get_data()), 'Text AssertionFailed'

     

            # think-time

            time.sleep(2)

    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

     

            assert (resp.code ==200), '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

     

            assert (resp.code ==200), '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

            assert (resp.status ==200), 'Bad Response: HTTP%s'% resp.status

            assert ('Example Web Page'in content), 'Text AssertionFailed'

    参考资料:

    http://testutils.org/multi-mechanize/

     

  • 相关阅读:
    ActiveMQ 默认用户名和密码
    # ActiveMQ连接超时问题(java.net.SocketException: Connection reset)
    SpringBoot(十) Logback 配置详解
    postgresql10以上的自动分区分表功能
    基于Redis实现延时队列服务
    Redis(十三):Redis分布式锁的正确实现方式
    Redis(十七):批量操作Pipeline
    Redis(十八):Redis和队列
    PostgreSQL SELECT INTO和INSERT INTO SELECT 两种表复制语句
    PostgreSQL 从文件时间戳获悉一些信息(如数据库创建时间)
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3320334.html
Copyright © 2011-2022 走看看