日历

« 2008-12-05  
 123456
78910111213
14151617181920
21222324252627
28293031   

最新来客

统计信息

  • 访问量: 924
  • 日志数: 15
  • 建立时间: 2008-08-20
  • 更新时间: 2008-11-17

RSS订阅

我的最新日志

  • 从 Jmeter输出数据导出excel表格

    2008-11-17

    时间匆忙,脚本未仔细测试

    require 'rexml/document'
    require 'win32ole'
    include REXML

    $input_file_name = ""
    $output_file_name = ""
    $column_names = ["Sample number", "Response Time", "Latency Time", "Time Start", "Status", "URL", "Return Code", "Return Msg", "Thread Number", "Date Type", "Bytes"]

    def print_usage
      puts "Usage: JmeterExtractor [JMeterResultFile] [ExcelFile]"
    end

    def check_input_file
      if File.exist? $input_file_name
        puts "input file "+ $input_file_name+" found"
      else
        puts "input file"+ $input_file_name+ " not found"
        exit
      end
    end

    def check_output_file
      if File.exist? $output_file_name
        puts "input file "+ $output_file_name+" found"
      else
        puts "input file"+ $output_file_name+ " not found"
        exit
      end
    end

    def init_excel
      # -4100 is the value for the Excel constant xl3DColumn.
      $ChartTypeVal = -4100;
     
      # Creates OLE object to Excel
      $excel = WIN32OLE.new("excel.application")
      $excel.Visible = true
      $excel.WorkBooks.Open($output_file_name)
      worksheet = $excel.WorkSheets.Add();
      worksheet.Activate
      worksheet.name = Time.new.to_i.to_s
      #  $excel.WorkSheets("testResults").Activate
    end

    def close_excel
      $excel.ActiveWorkbook.Close(1)
      $excel.Quit()
     
    end

    def get_start_time time
      usec = time % 1000
      sec = time/1000
      Time.at(sec).to_s + " " + usec.to_s + "ms"
    end

    def get_status s
      if (s.eql? "true")
        "success"
      else
        "fail"
      end
    end

    def print_excel_title
      $column_names.each_index do |i|
        $excel.Cells(1, i+1).value = $column_names[i]
      end
    end

    arg_len = ARGV.length
    #puts arg_len
    case arg_len
      when 0
      $input_file_name = "C:/tool/jakarta-jmeter-2.3.1/workspace/1"
      $output_file_name = "C:/tool/jakarta-jmeter-2.3.1/workspace/result.xls"
      when 1
      $input_file_name = ARGV[0];
      $output_file_name = "C:/tool/jakarta-jmeter-2.3.1/workspace/result.xls"
      when 2
      $input_file_name = ARGV[0];
      $output_file_name = ARGV[1];
    else
    end
    #puts $input_file_name
    #puts $output_file_name
    check_input_file
    check_output_file
    init_excel
    input_file = File.new($input_file_name);
    doc = Document.new(input_file)
    $element_index = 0
    doc.elements.each("//httpSample") do |e|
      $element_index += 1
      print e.attributes["t"]
      print " "
      print e.attributes["lt"]
      print " "
      print e.attributes["ts"]
      print " "
      print e.attributes["s"]
      print " "
      print e.attributes["lb"]
      print " "
      print e.attributes["rc"]
      print " "
      print e.attributes["rm"]
      print " "
      print e.attributes["tn"]
      print " "
      print e.attributes["dt"]
      print " "
      print e.attributes["by"]
      puts
      STDOUT.flush
      print_excel_title
      $excel.Cells($element_index+1, 1).value = $element_index
      $excel.Cells($element_index+1, 2).value = e.attributes["t"]
      $excel.Cells($element_index+1, 3).value = e.attributes["lt"]
      $excel.Cells($element_index+1, 4).value = get_start_time(e.attributes["ts"].to_i)
      $excel.Cells($element_index+1, 5).value = get_status(e.attributes["s"])
      $excel.Cells($element_index+1, 6).value = e.attributes["lb"]
      $excel.Cells($element_index+1, 7).value = e.attributes["rc"]
      $excel.Cells($element_index+1, 8).value = e.attributes["rm"]
      $excel.Cells($element_index+1, 9).value = e.attributes["tn"]
      $excel.Cells($element_index+1, 10).value = e.attributes["dt"]
      $excel.Cells($element_index+1, 11).value = e.attributes["by"]
    end

    close_excel

  • jar内的类如何读取jar内的配置文件

    2008-11-17

    以xml为例:

    JarFile jarFile = new JarFile(getClass().getProtectionDomain().getCodeSource().getLocation().getFile().toString());
        JarEntry entry = jarFile.getJarEntry(internalConfigPath);
        document = saxReader.read(jarFile.getInputStream(entry));
        jarFile.close();

  • TestNG 标签小结

    2008-10-16

    @Configuration 这个标签只在早期版本使用,已被弃用

    @BeforeSuite 测试套件前执行,测试套件在testng.xml中定义

    @AfterSuite  测试套件后执行,测试套件在testng.xml中定义

    @BeforeTest  整个测试开始前执行

    @AfterTest      整个测试结束后执行

    @BeforeGroups 属于指定的组的第一个测试方法执行前发生

    @AfterGroups  属于指定的组的最后一个测试方法执行后发生

    @BeforeClass 当前测试类执行前发生

    @AfterClass  当前测试类执行后发生

    @BeforeMethod 每个测试方法执行前发生
    @AfterMethod 每个测试方法执行后发生

     

    参数:

    alwaysRun         对于before类的方法来说该参数为真表示不管该方法属于哪个组都会执行;对于before类的方法来说该参数为真表示上一个测试方法无论失败或跳过都不影响这个方法的执行

    dependsOnGroups   等某些组的方法执行完后执行

    dependsOnMethods  等某些方法执行完后执行

    enabled           为真时激活

    groups            从属的组

    inheritGroups     继承定义在类的级别的组

     

    @DataProvider      数据源,标记的方法必须返回Object[][]类型。每个Object[]可以是一个参数列表。

    参数:

    Name       数据源名称

     

    //This method will provide data to any test method that declares that its Data Provider

    //is named "test1"

    @DataProvider(name = "test1")

    public Object[][] createData1() {

     return new Object[][] {

       { "Cedric", new Integer(36) },

       { "Anne", new Integer(37)},

     };

    }



    //This test method declares that its data should be supplied by the Data Provider

    //named "test1"

    @Test(dataProvider = "test1")

    public void verifyData1(String n1, Integer n2) {

     System.out.println(n1 + " " + n2);

    }
     
    public static class StaticProvider {

      @DataProvider(name = "create")

      public static Object[][] createData() {

        return new Object[][] {

          new Object[] { new Integer(42) }

        }

      }

    }



    public class MyTest {

      @Test(dataProvider = "create", dataProviderClass = StaticProvider.class)

      public void test(Integer n) {

        // ...

      }

    }
     

     

    @Factory         标记工厂方法,产生测试类,返回Object[]类型

    public class WebTestFactory {
      @Factory
      public Object[] createInstances() {
       Object[] result = new Object[10];  
       for (int i = 0; i < 10; i++) {
          result[i] = new WebTest(i * 10);
        return result;
      }
    }

    and the new test class is now:

    public class WebTest {
      private int m_numberOfTimes;
      public WebTest(int numberOfTimes) {
        m_numberOfTimes = numberOfTimes;
      }

      @Test
      public void testServer() {
       for (int i = 0; i < m_numberOfTimes; i++) {
         // access the web page
        }
      }
    }

     

    @Parameters     描述如何向测试方法传递参数

    参数:

    value             一组变量来填满该方法的参数

    @Parameters({ "first-name" })

    @Test

    public void testSingleString(String firstName) {

     

    @Parameters("db")

    @Test

    public void testNonExistentParameter(@Optional("mysql") String db)

     

    @Test            测试方法或测试类

    参数:

    alwaysRun         所依赖的方法即便失败了也会执行

    dataProvider      指定数据源名称

    dataProviderClass 从指定类找数据源,不指定则从当前类或父类中找

    dependsOnGroups   依赖的组

    @Test(groups = { "init" })

    public void serverStartedOk() {}



    @Test(groups = { "init" })

    public void initEnvironment() {}



    @Test(dependsOnGroups = { "init.* })

    public void method1() {}

     

    dependsOnMethods  依赖的方法

    @Test

    public void serverStartedOk() {}



    @Test(dependsOnMethods = { "serverStartedOk" })

    public void method1() {}

     

    descrīption       方法的描述

    enabled           是否有效

    expectedExceptions   期望抛出的异常,如果无异常或不同的异常抛出该测试失败

    groups            所属的组

    @Test(groups = { "functest", "checkintest" })

     

    invocationCount   该方法调用的次数

    @Test(threadPoolSize = 3, invocationCount = 10,  timeOut = 10000)

    public void testServer() {

     

    invocationTimeOut 该测试方法的最大执行时间总时间,是多次调用的累加

    successPercentage 期望的成功比例

    sequential        仅对类一级的标记有效,为真时表示该类中所有方法顺序执行。

    timeOut           整个测试的最大执行总时间

    threadPoolSize    线程池大小。该测试方法按invocationCount的值启动多线程

  • Web Service 性能测试, soapUI还是Jmeter?

    2008-9-17

    经常有人问我web service的性能测试是用JMeter好还是SoapUI好。说句实话这两款都是非常优秀的开源Web Service性能测试工具,简单地说哪个更好真不太容易。影响Web Service性能测试的因素太多到底谁的结果更准确一些很多时候并不主要取决于测试工具。在soapUI官方网站上有一个文章比较了这两款工具,我将要点抽出来加以分析希望能反映它们的特点。

    JMeter在整个负载测试的优越性是毋庸置疑的,它覆盖了常见的各种测试类型,如HTTP, JDBC, JMS 和SOAP。单就Web Service测试,作者做了一个简单的实验,但并没有涉及太多的细节。

    试验准备:本地Web Service,运行于JBoss 4.0.3SP1,每个简单请求在4种不同负载下执行5000次,分别是1线程,5线程,10线程和25线程。在SoapUI中为简单起见均使用简单负载策略,并且五执行延时。要分别记录关闭连接和非关闭连接方式的数据。关闭连接方式是指每次请求完毕后关闭连接。反之则是让连接仍然保持打开以等待下个请求,显然会省去很多额外开销。在JMeter中也可以做类似配置,如线程数为1,循环次数5000或线程数25,循环200次。

    环境:WinXP SP2, Pentium M 1.8 1 G RAM, JRE 1.5.0_06.

    结果:

    Threads

    jmeter

    soapUI

    soapUI (*)

    soapUI cmdline

    soapUI cmdline (*)

    1

    8 ms, 105 TPS

    6.78 ms, 147 TPS

    10.7 ms, 94 TPS

    5.75 ms, 174 TPS

    10 ms, 99 TPS

    5

    43 ms, 110 TPS

    38.7 ms, 128 TPS

    23.7 ms, 211 TPS

    30.4 ms, 164 TPS

    24 ms, 210 TPS

    10

    86 ms, 112 TPS

    82 ms, 122 TPS

    46.5 ms, 215 TPS

    61 ms, 164 TPS

    38 ms, 262 TPS

    25

    214 ms, 114 TPS

    204 ms, 123 TPS

    124 ms, 202 TPS

    159 ms, 157 TPS

    95 ms, 263 TPS

    其中带*的是非关闭连接模式下测试的结果。从结果中看出Jmeter的测试值均较SoapUI偏大,但与UI连接关闭模式下执行结果相差无几。实验未给出JMeter命令行下的测试结果。但从经验来讲,命令行执行方式避免了测试工具本身带来的巨大资源消耗,更接近真实值。soapUI在命令行连接不关闭模式下TPS随线程的增加在初期有明显上升的。

     

    从计时机制来看,JMeter 用的是System.currentTimeMillis(),soapUI用的是更为精确的System.nanoTime().

     

    综上所述(文中没有点明,但这是显而易见的),soapUI在单纯的Web Service 测试时有明显的优势,当要综合其他测试时可以组合使用多种工具。

     

    当然这是soapUI自己做的实验,难免有王婆卖瓜之嫌,有兴趣的朋友可以自己设计实验来测试一下。

  • oracle 系统表摘要

    2008-9-01

    dba组的表需要以dba权限访问
    dba_users 用户
    dba_data_files 数据文件
    dba_tablespaces 表空间
    dba_free_space 空闲表空间
    dba_objects 数据库所有对象
    dba_tables 所有表
    dba_extents

    user_tab_columns 所有列
    dba_indexes 索引
    dba_ind_columns 索引列
    user_indexes
    user_ind_columns

    dba_sequences 序列
    dba_views
    all_views 视图
    dba_clusters 簇
    dba_snapshots 快照
    dba_trigers 触发器
    user_source
    user_errors
    user_constraints 约束
    user_jobs 作业
    dba_jobs
    user_jobs_running
  • 好书学习:极限编程释疑--拥抱变更 3

    2008-8-25

    第二章 一个典型的开发场景
    本章作者用一段开发人员之间的对话来阐述了几个在极限编程和敏捷开发中极为重要的概念:
    1。Pair Programming,结对编程,有助于提高效率和减少错误,这个模式经常听说,但好像在国内很少看到
    2。测试驱动开发,先写测试,由于还没有代码实现,测试肯定 fail, 然后加少量代码,再写测试,再做实现,如此循环,直到你无法想到新的测试,现有的测试也都通过了,这个模块才算完成了。好处是不会写多余无用的代码,也不容易漏掉有用的代码,显著的问题会很早被发现。开发人员在进入到下个模块的开发时对已完成的部分有充足的信心。
    3。结对编程并不只做实现和测试,其实设计也是在这个过程中演化成熟的。这是一种典型的“小设计”模式。
    4。持续集成。新功能一完成立即与老功能集成并测试。
  • 好书学习:极限编程释疑--拥抱变更 2

    2008-8-25

    第一章:风险,最根本的问题
    软件开发面临以下问题:
    1。延期
    2。过度延期造成项目取消
    3。没用多久就因为费用或质量问题被取代
    4。缺陷太多无人问津
    5。不能满足业务需求
    6。业务需求出现变更
    7。很多费大劲做的软件功能没有最终实现商业利益
    8。人员变更,项目人员感到厌烦而离开

    极限编程解决以上问题:
    1。极限编程采用短迭代周期,任务划分成1-3天的粒度,功能划分优先级,一旦延期损失的只是最次要的方面。
    2。快速的迭代和版本发布使问题及早暴露,迅速调整,不至于问题恶化到项目中止
    3。极限编程用一整套测试来保证系统有一个质量基线,那么后来的变更也不至于严重损坏该系统。(即便出了问题,还可以退回到原有系统)
    4。在极限编程中测试贯穿始终,从单元测试到系统测试,保证了低缺陷率
    5。客户是团队的一部分。由于客户是对需求最熟悉的人,他们的参与和持续反馈保证了建造的系统不会脱离实际的业务需求
    6。在短迭代周期的模式下,只需要做少量工作既可应对需求变更。对很多极限编程的工程师来说几乎感觉不到变更的困扰
    7。坚持最大商业价值的功能先实现
    8。每个成员可以对工作量作预估,并持续提高估计的能力,避免由于估计不足造成的强制加班;也鼓励组织内部沟通,消除“孤独感”。新成员循序渐进地融入项目。

    要解决以上问题要求所有的人,包括开发人员,项目经理和客户对极限编程的新准则认可和接受,并在实践中贯彻始终。

  • 好书学习:极限编程释疑--拥抱变更 1

    2008-8-25


    作者背景:
    Kent Beck,在俄勒冈大学获得计算机科学硕士学位。极限编程的创始人,是敏捷开发17个最初申明人之一,倡导了测试驱动开发,和Eric Gamma共同创建了JUnit单元测试框架,1999年和2003年两度获得Jolt奖。
    著作列表:
    书:
        * Smalltalk Best Practice Patterns. Prentice Hall, 1996. ISBN 0-13-476904-X.
        * Kent Beck's Guide to Better Smalltalk : A Sorted Collection. Cambridge University Press, 1998. ISBN 0-521-64437-2.
        * Extreme Programming Explained: Embrace Change. Addison-Wesley, 2000. ISBN 0-201-61641-6. Second edition 2005 with Cynthia Andres. ISBN 0-321-27865-8. (Jolt productvity award 1999 [2])
        * Planning Extreme Programming. With Martin Fowler. Addison-Wesley, 2000. ISBN 0-201-71091-9.
        * Test-Driven Development: By Example. Addison-Wesley, 2002. ISBN 0-321-14653-0. (Jolt productvity award 2003 [3])
        * Contributing to Eclipse: Principles, Patterns, and Plugins. With Erich Gamma. Addison-Wesley, 2003. ISBN 0-321-20575-8.
        * JUnit Pocket Guide. O'Reilly, 2004. ISBN 0-596-00743-4.
        * Implementation Patterns. Addison-Wesley, 2008. ISBN 0-321-41309-1.
    论文:
        * Using Pattern Languages for Object-Oriented Programs. With Ward Cunningham. OOPSLA'87.
        * A Laboratory For Teaching Object-Oriented Thinking. With Ward Cunningham. OOPSLA'89.
        * Simple Smalltalk Testing: With Patterns. Origins of xUnit frameworks.
  • 如何用Ruby连接SQL Server 2005

    2008-8-25

    require 'win32ole'
    connection = WIN32OLE.new('ADODB.Connection')
    connection.open("Provider=SQLOLEDB.1;User ID=sa;password=xxxx;Data Source=localhost,1433;Initial Catalog=mydb")

    最重要的一点是即使默认端口1433也要加上,不然会报错:
    sql.rb:27:in `method_missing': open (WIN32OLERuntimeError)
        OLE error code:80004005 in Microsoft OLE DB Provider for SQL Server
          [DBNETLIB][ConnectionOpen (Invalid Instance()).]Invalid connection.
        HRESULT error code:0x80020009
          Exception occurred.    from sql.rb:27:in `open'
        from sql.rb:63
  • Sql server 2005 express 的数据导出

    2008-8-21

    Microsoft Sql Server Management Studio Express在独立安装下只提供表结构的查询导出,要备份数据就只能备份整个数据库。在测试中有时我们需要向开发提供测试数据以供缺陷重现,庞大的数据库备份文件就不太方便了。数据转换向导DTSWizzard提供了这个功能。这个工具在MS SQL Server 2005 Express Toolkit 包中。事实上当完整安装Toolkit时Management Studio也同时装上了。下面是Toolkit SP2 英文版的官方下载地址:

    http://www.microsoft.com/downloads/details.aspx?FamilyID=E8AD606A-0960-4EFD-8BD7-B21370C7BE2B&displaylang=en

    要注意的是在安装前要将原先安装的Management Studio 卸载干净,否则可能会导致安装失败。
Open Toolbar