对 Rational Performance Tester 数据池的改进(2)

发表于:2012-03-26来源:未知作者:娃娃点击数: 标签:
这个 xmi 文件实际就是我们数据池实例 aa 的序列化后的形式,系统在实际调用时会将其反序列化同时将相关的数据 load 到内存中去。在 Rational Performance T

  这个 xmi 文件实际就是我们数据池实例 aa 的序列化后的形式,系统在实际调用时会将其反序列化同时将相关的数据 load 到内存中去。在 Rational Performance Tester 中打开这个 xmi 文件,可以清晰的看到它的层次结构,同时可以对它进行修改。

  图 2: 层次结构

  采用 EMF 设计的一个很直接的好处是,系统可以自动的根据模型生成代码,同时实现了 UML 模型,XML Schema, 注释过的 Java 接口表现模型的统一。但在实际环境中,采用 Rational Performance Tester 内置的 DataPool 还是有很多不太方便的地方,比如:

  要经常对文件中的数据进行变化,然后再重新测试时

  很多时候测试完后,数据就暂时没用了,因为状态已经更新了,为此需要对测试数据进行替换,但在 RPT 目前的这种序列化反序列化的机制中,要实现这一点并不容易,所以体现在界面中的操作实际上是比较繁琐的,表现为:

  要重新加入一个新的 Pool

  需要对原来的变量去掉关联

  关联新的 Pool 中的变量

  如果你的变量比较多,还是非常繁琐的,而且不是一种最好的解决办法。

  当测试数据很大,比如文件大概 50M 或更多时

  这时候内置的机制会产生一些问题,装载数据时比较慢。这在早期的 6.x 版本中经常遇到,但现在 70 有没有这个问题倒是需要看看底层机制是否有更改。

  正因为上面的问题,同时还频繁在实际的测试过程中遇到,因此找到一种更好的替代方案对于实际的项目更加迫切,好在 RPT 建立在 TPTP 的架构上,也就意味着建立在纯粹的 Java 的实现机制下,因此提供了让人很方便的插入 Java 代码的方式,使得很多的扩展和增强成为可能。下面我们就来谈谈如何解决这两个问题。

  Rational Performance Tester DataPool 的扩展

  为了扩展 DataPool 我们决定对这个环节进行重新的设计,原则如下:

  考虑对真实测试性能影响最小的原则,我们把所有的数据都放在文本文件中,变量间通过逗号来进行分隔。

  考虑到内存的开销,同时不需要把所有的数据都读入到 JVM 中进行处理的原则,我们通过了一个 ArrayList 来存放一次读入的数据,这些数据会分配给每个 Virtual User, 同时如果读到最后行时,会重新调用方法进行对 ArrayList 中数据的刷新。

  通过变量来控制一次读入的文件行数。

  一开始的时候考虑把通过二维数组来进行变量的读取,但后来在调试过程中发现,很难解决不同的变量读取同一行的问题,往往在一次读完后就指针就指到下一行去了,而因 RPT 本身并不是全部的 Java 脚本,而是 Java 脚本和页面表示的混合,Java 脚本和页面间其实是通过变量来进行沟通的,这造成的一个很现实的问题是,如果我们仅仅获取一个变量而不是每行的时候,无法控制在哪条语句后移动 cursor。后来就改变了设计,采用了一起获取一行的方式,对于变量的返回通过对行的解析得到。

  通过 PoolLoad 定义静态的数据池类

  通过 getLine 返回当前 VU 对应的行

  通过 getVar 解析返回行,从而返回需要的变量

  经过设计的类图如下:

  图 4: 经过设计的类图

  关键代码的解释:

  RPTDataPool.java:主要用于将记录以分页的形式从文件中读入到 ArrayList 中

  首先定义需要的变量:

Private String DataPoolFileName;// 定义数据池文件存放的位置,运行时会由 PoolLoad.java 装入
        private ArrayList DataPool;// 存放每次从数据池中读出的记录
        private int cursor = 0;// 当前记录的光标
        static private int pageno = 1;// 根据每页的大小 (PageSize), 目前光标停在哪页
        private int pagesize = 500;// 每次 load 进 DataPool 的记录数量

  构造函数 RPTDataPool:

  调用 fillPageByLine 方法,把文件的第一个页面存入到变量 DataPool 中来。

public RPTDataPool(String fileName ) {
    
    ……
    
    fillPageByLine( DataPoolFileName, DataPool, 1);
}        

  fillPageByLine: 每次到了页面的记录末尾,都会被调用,从而把相关的记录读到 DataPool 中来。

private boolean fillPageByLine(String fileName, ArrayList FileLines, int Pageno) {
    // 通过 ReadLine 读文件 ;
    while (line !=null) {
    // 当前行数在关注的页面中, pageno 通过参数传入
    if ((lineno>=pagesize*(Pageno-1))&&(lineno<pagesize*Pageno)) {
        FileLines.add(line);// 把当前记录加入 ArrayList
        line=br.readLine();// 记录下移
        lineno++;// 行数增加
    } else if (lineno<pagesize*(Pageno-1)) {// 当前行数还没到关注的页面
        line=br.readLine();// 记录下移
        lineno++;// 行数增加
    } else if (lineno >= pagesize*(Pageno)) {// 当前行数超过关注的页面
        break;// 退出
    }
}

原文转自:http://www.ltesting.net