发布新日志

  • 基于selenium测试框架设计之MVC模式 2

    2013-06-24 18:03:00

    测试控制(control)从大的来讲就是测试用例结构流程的控制,从小的来讲就是如何驱动测试的展开
    selenium测试通常和单元测试框架整合,比如在java上就是junit或者testng。单元测试框架的作用就是控制测试执行的策略。testng相较junit提供更多的控制方式,比如组策略,类控制等,这种灵活的机制很大程度地扩展了我们设计执行框架的空间。
    有时我们要执行所有回归测试用例,但更多的时候执行部分。最简单的办法是把要测试的类列在testng配置文件里,然后按类执行。有时候我们需要的测试用例混杂在不同的类里边,那组策略就比较合适了。
    在设计测试结构时有个重要的因素时测试的依赖性。适度的依赖性可以提升测试效率,但是牺牲测试独立性。比如登陆和浏览是两个用例。登陆是浏览的前提用例。我们来看一下两种不同的设计方式
    一:
    测试准备-》登陆-》浏览-》测试关闭

    二:
    测试准备-》登陆-》测试关闭-》测试准备-》登陆-》浏览-》测试关闭

    方式一的好处是减少了测试时间,方式二的好处两个用例可以独立执行,但是重复代码多,设计要求高。

    测试准备-》登陆-》测试关闭
    测试准备-》登陆-》浏览-》测试关闭
    当测试用例完全独立的时候我们可以采用并发的方式缩短测试时间。但是实际情况中这种依赖性很难完全消除,还有些约束条件要考虑,比如A先完成和B先完成可能将导致不同的结果。所以在设计的时候就要充分考虑这些情况以保证选择性测试可以实现。
    单个测试用例独立性集中体现在手工测试和自动测试的集成。有些集成管理工具比如QC允许测试人员启动单个自动测试脚本并传回结果。在testng框架下充分利用不同层级的setup和teardown可以很大程度提升测试的独立性。

    下面谈一下测试的驱动模式。常见的是关键字驱动和数据驱动。还有事件驱动,即测试的顺序由事件的发生顺序而确定,而行为驱动可以看作是事件驱动的一种特例。基于selenium的框架用于web测试,因此关键字驱动是最直观也是最重要的驱动方式。

    设计测试过程的时候最重要的原则是可读性。个人一直认为测试代码的设计和应用程序代码的设计原则是不同的。应用程序注重的外部行为,即人们只关心这个接口能做些什么,确不关心内部到底怎么做的。测试代码则不同,读代码的人非常需要了解内部细节和步骤是的实现。所以测试脚本更具有面向过程而不是面向对象的本质(所以我们称之为脚本)。人对过程的理解相当程度是线性的,所以要尽量减少代码的分支和跳转。重复代码在一定程度上是可接受的,条件是增加可读性。方法的封装要适度。比较理想的是代码语句和手工测试用例步骤相呼应。尽管精巧的命名可以大大提升可读性,测试代码注释行的量仍然应当比应用程序代码多得多。
  • 基于selenium测试框架设计之MVC模式

    2013-06-20 19:46:38

    这里只是借用MVC这个名字,其实和web应用的mvc模式不是一个概念

    M是model,就是数据模型,从测试来讲包含测试数据和测试对象数据。
    -测试数据管理。在数据驱动的场景下可能要用到大量测试数据,可以是随机或特定约束下生成的,或者从外部导入。无论哪种都需要支持类和方法来生成,存储,操纵或转换。
    测试数据的格式常见的有csv,xml,excel,数据库等。在java里配置数据一般存在xml或者properties文件,便于读取和管理,而大量的数据纪录则用csv比较经济。数据结构来讲映射到对象比多维数组更便于检索,但开销也大一些。
    数据库存测试数据增加了依赖性,但是方便复杂的查询。各种结构可谓各有利弊,从个人实践上讲csv是最常用的输入输出格式,其中一个重要因素是csv转换excel非常方便。

    -测试对象数据。QTP有动态和静态对象库的概念。这种机制有利于脚本的维护,完全可以借鉴到我们自己的框架设计体系中来。selenium里可以标示网页对象的是Locator,webdriver里是By。类型不外乎name,id,class,xpath,jquery locator等,描述方式接近于QTP的描述性标示。Terrillium 框架采用了groovy混合编程,就是利用了脚本语言在描述层次对象上的灵活性。假如用java实现的话也可以用递归的方式来检查组合对象,比如表单。表单对象有若干子对象,比如输入框,提交按钮,下拉框等。一个一个对象检查有些累赘,改进后伪代码如下
    checkCombObject(WebObject object){
    if(object.hasChildren()){
    for(Object obj : object.allChildren){
    checkCombObject(obj);
    }
    }
    assertObjectMatch(expectedObj, object);
    这样一行代码就可以检查整个表单
    checkCombObject(webForm);

    先写到这里,下次再写V(View)和C(Control)
  • 自动化测试 双线开发

    2013-06-19 16:48:20

    总结一下这几年来自动化测试管理的经验,觉得比较有价值的一条就是双线开发。其实都是些显而易见的 东西,也谈不上是创新,但是这样实践的貌似不多
    一条线是框架和可重用过程库的开发,另一条就是测试脚本的开发
    有一个很深的感触就是设计良好的测试框架能大大提升脚本开发的效率和降低维护难度,然而测试人员往往不具备这样的 设计能力。框架开发更合适由SA和开发人员设计完成,具备优良的接口设计,定期发布。而自动化测试人员则专注于脚本开发。这样能达到人力配置的最大优化。

  • CI 远程启动selenium测试

    2013-06-19 16:33:17

    一般情况下CI(比如jenkins)都在本地执行测试代码,但是假如CI是配置在linux/unix上的话启动selenium就比较麻烦,还要先起xwindow。不如专门指定一台windows客户端来执行浏览器上的测试。过程简述如下,以maven为例
    1. 在CI的maven配置中传一个选项参数给测试代码,比如
    mvn test -Dhost=[测试客户端IP] -Dremote=true
    2. 在测试类setup的时候读取
    Boolean clientHost = System.getProperty(“host”);
    Boolean isRemote = System.getProperty(“remote”).equals(“true”);
    3.假如是远程模式的话就初始化远程驱动
    driver = new RemoteWebDriver(new URL("http://“ + clientHost + ”:4444/wd/hub"), DesiredCapabilities.firefox()); 
    当然不要忘记启动selenium server
  • Git 安全认证

    2013-06-18 16:40:50

    随着GitHub短短五年里在开源领域里异军突起,Git技术越来越被人重视。不少公司已经着手将代码迁移到Git上。
    Git 也和SVN一样支持用户名密码和密钥认证。密钥认证安全性更好,但配置也相对繁琐。RSA密钥有两种格式,一种是Openssh,还有一种是putty 工具生成的ppk密钥对。
    在Unix上配置相对简单,只要把公钥上传到服务器端,注意必须放在用户根目录的.ssh子目录下,而且该用户必须拥有读权限,通常设置600
    要注意的是有些常用的集成软件比如Jenkins的git插件只支持密钥认证。还有一个是NetBeans只支持Openssh的密钥文件格式。
    Windows底下的配置问题比较多,默认的ssh应该是在用户目录下。Win7还好些,路径没有空格。XP路径有空格(Settings and Documents), 会搞出一些莫名其妙的问题。建议还是用Git Bash来检查配置比较容易找到问题。
  • 小议xstudio

    2013-06-17 17:06:56

    最近再评估测试管理工具,发现xstudio是近几年来看到过的最优秀的测试管理平台之一,即便相比较QC, TD也不遑多让。而考虑到基础版的xstudio居然还是免费的,这个。。
    简单概括一下xstudio的几大优点:
    1。 完全基于java,可以跨平台安装,对于采用unix/linux作为服务器的公司非常合适
    2。 超全面的测试管理功能,从需求管理,测试策略管理,缺陷管理,各种测试工具的自动化测试集成,测试报告,还支持敏捷项目的测试管理从功能上来讲实在无懈可击
    3。 极度开放的体系,可以开发适合自己公司的测试启动器(Launcher),丰富测试执行方式,还可以和绝大多数测试软件集成使用。主从结构的测试分派方式也很实用

    当然拉这个工具也不是完美无缺:
    1。 软件不够成熟,经常出错,文档不齐全
    2。 导入导出功能不强,从其他系统或Excel迁移测试用例时需要额外脚本支持
    3。 只有胖客户端,消耗资源较多
    4。 数据模型较复杂,学习周期长
    5。 rest API还不够丰富

    总的来将这个软件潜力巨大,对于寻求低成本软件测试管理的企业几乎是不二选择。后面假如有时间我总结一下常见问题的解决方法。
  • Emma Cobertura and OC4J

    2010-09-07 15:46:14

    几种代码覆盖率工具在和web应用集成的时候都有些问题。Cobertura 和emma都是在程序退出时更新覆盖率数据文件的。但是由于某些原因数据文件没有能得到更新。经过一番研究发现都有弥补的办法。

    Cobertura:

    3.     应用服务器以oc4j为例,其他类似。将 Cobertura.jar 文件复制到应用服务器workspace公共lib,  对于oc4j,来说就是 applib.

    4.    解开下载来的cobertura包里有一个文件: flushCobertura.war,将其部署到oc4j.

    fa    访问地址 http://localhost:8888/coberturaFlush/flushCobertura

    旧可以强制将数据导出到cobertura.ser文件。位置默认在home目录。要记得事先将原始文件放在此目录下,不然得到的覆盖率都是100%

    6.    

        Emma:

        最新版本的emma有ctl工具,可以在应用服务运行时强制导出覆盖率数据,用法为:

    C:\tools\emma>java -cp emma.jar emma ctl -connect localhost:47653 -command coverage.get,coverage.ec

    用命令行生成报告时数据文件之间的逗号前后千万不能加空格,否则就会报数据找不到。

    另外运行ctl命令时要是总是有RPC连接错误说明处理过的类没有就载入虚拟机,需要在浏览器打开该应用,保证至少有一个java类(通常首先执行的是servlet类)执行。

  • xfire NamespaceURI cannot be null

    2010-07-27 14:27:10

    用xfire生成webservice 或客户端代码时看到如下错误
     XMLStreamException: xfire NamespaceURI cannot be null.
    有两种可能性:
    1。 missing jar: wstx-asl.jar
    2. 自动声称的代码里在不同的包里生成了相同的类。
  • Got empty result from method.getDeclaredAnnotations

    2010-07-20 08:05:09

    Was very confusing:
    @MyAnnotation
    myMethod(){
    ...
    }

    Then write code like:

    ...// Get the method
    assert(method.getDeclaredAnnotations.length==1);

    The test failed. After hours research, it turned out that the reason is the annotation is not declared as RUNTIME. Correct it:

    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
    ...

    By the way getDeclaredAnnotations method doesn't return annotations inherited from parent class.This is how it distinguish from getAnnotations method.
  • NTLM authentication with SoapUI

    2010-07-19 09:42:31

    Spent hours figuring out testing an interface with soapUI today. The interface is authenticated with NTLM v2, which brings problem. soapUI doesn't support NTLM very well. Found a work around from google search:

    1. Download Burp Suite from http://www.portswigger.net/suite/ and crank it up.
    2. On Burp's "Proxy : Intercept" tab, click the button to turn intercept off.
    3. On Burp's "Proxy : Options" tab, make sure it's set to an unused port, the default is 8081
    4. On Burp's "Comms" tab, tick "do www authentication" and add a setting for the server you wish to hit. Also tick "prompt for credentials on authentication failure"
    5. Switch to Burp's "Proxy : History" tab so you can see requests going through.
    6. In SoapUI, choose File > Preferences, then select "Proxy Settings". Enter Host "localhost" and port "8081".
    7. Use SoapUI as normal. It will send requests through Burp Proxy, which will do the NTLM authentication for you.
    Tested and it works pretty well. Burp Suite is powerful !!! :)

  • QTP 10 之本地系统资源监控

    2010-01-02 07:25:06

    本来作为mercury的主打产品,在功能测试中加入性能监控不是什么难事,怪就怪在居然一直等到了10.0. 不过晚来总比不来好,看看它能做什么。
    录制了一个简单的google搜索脚本,跑一遍,通过。
    然后在setting里设置下内存上限,设为50M

    再执行一下,还是通过。最后设成30MB,测试失败。

    上面是系统监视器的图。
    这个功能帮助测试人员想快速了解下当前版本程序对系统资源的消耗情况。还可以看到哪个步骤造成了大的系统消耗。
  • Scrum 项目实践之工作量估计

    2009-02-01 19:40:52

    在敏捷开发中,每个迭代开始前的工作量估计几乎已经成为了标准环节,但总觉得费时又费力,两三周的工作要开一两天的会都讨论不清楚,讨论再讨论,投票再投票。

    http://www.scrumalliance.org/articles/116-a-cure-for-task-estimation-obsession

    一文给人以很多启迪。在满足诸如稳定速率等前提下面向任务的燃尽图要优于面向工作量,其原因就是每个任务的完成都有产出而工作量的投入却不一定,面向任务的视角更能客观地反映项目的进程。更重要的是单纯任务分解细化要远比估计时间省事。

  • Selenium 证书cybervillainsCA.cer过期?

    2008-12-24 14:02:34

    要用Selenium测试ssl就要用它的伪证书。

    最近发现老版本seleniumRC带的cybervillainsCA.cer过期了,又不允许升级,看了下,只要删除在浏览器(IE)里安装的老证书,然后把新证书更新到selenium-server.jar/sslSupport就行了。附件更改扩展名到.cer就可以了。

    自己生成证书:

    1. copy selenium-server.jar/sslSupport/*.ser to a new folder, such as folder "keystore"

            Remove file cybervillainsCA.jks, if it is in folder "keystore"

        2. Use below java code to generate/update file cybervillainsCA.cer

            import cybervillains.ca.KeyStoreManager;

            public class CertGenerate{

                public static void main(String[] args){

                    KeyStoreManager ksm = new KeyStoreManager(new File("keystore"));

                }

            }

  • 测试驱动编程

    2008-12-15 18:35:15

    很好的总结性发言。对测试驱动有比较长的实践了,有很好的效果,但感觉要真正习惯还是不容易的。

    http://www.ibm.com/developerworks/cn/java/j-xp042203/index.html

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

    2008-11-17 15:12:13

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

    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 13:35:15

    以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 15:18: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-09-17 11:33:10

    经常有人问我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-09-01 12:21:06

    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-08-25 19:35:38

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