扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:聂健 来源:论坛整理 2007年11月17日
关键字: Rational Performance
前言
在性能测试中,我们往往遇到这样的一些问题,比如需要通过不同的用户进行登录操作,或者需要动态的输入数据,在测试工具中往往我们是通过数据池来进行完成的。比较全面的数据池的设计往往会考虑用户数据的来源,比如文件,数据库等多种形式,但其实如果采用直接映射数据库中的某些列来进行实现,虽然在操作上会省下很多数据加工的时间,但在实际运行过场中会有诸多缺点,主要体现在每个用户每次获取数据时就需要消耗大量的时间,因为往往数据库在
Rational Performance Tester 内置的 DataPool 的实现
Rational Performance Tester 内置的数据池采用了 TPTP 的前身 Hyades 测试框架的实现方式,也就是通过 EMF 进行实现。其
图 1: 设计图
其中比较主要的几个概念是:
往往我们在通过 RPT 的界面建立数据池或者从 CSV 文件导入数据池时,会发现在我们的 workspaces 项目的根目录下中生成了一个 .datapool 的文件,把文件通过 winrar 解开,可以看到是一个 xmi 文件,格式如下:
<?xml version="1.0" encoding="UTF-8"?> <Common_Datapool:DPLDatapool xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:Common_Datapool="http://www.eclipse.org/hyades/models/common/datapool.xmi" id="E123A884D00625FC60097F300AD111DC" name="aa"> <equivalenceClasses id="E123A884D00625FC6021E9300AD111DC" name="String"> <records> <cells value="<Literal>eric</Literal>" variable= "E123A884D00625FC600C8C700AD111DC "/> <cells value="<Literal>ericnie</Literal>" variable="E123A884D00625FC602062900AD111DC"/> </records> <records> <cells value="<Literal>eric1</Literal>" variable="E123A884D00625FC600C8C700AD111DC"/> <cells value="<Literal>ericnie1</Literal>" variable="E123A884D00625FC602062900AD111DC"/> </records> <records> <cells value="<Literal>eric2</Literal>" variable="E123A884D00625FC600C8C700AD111DC"/> <cells value="<Literal>ericnie2</Literal>" variable="E123A884D00625FC602062900AD111DC"/> </records> <records> <cells variable="E123A884D00625FC600C8C700AD111DC"/> <cells variable="E123A884D00625FC602062900AD111DC"/> </records> </equivalenceClasses> <datapoolSpec id="E123A884D00625FC60097F310AD111DC"> <variables id="E123A884D00625FC600C8C700AD111DC" name="name" type="String”/> <variables id="E123A884D00625FC602062900AD111DC" name="password" type="String”/> </datapoolSpec> </Common_Datapool:DPLDatapool> |
图 2: 层次结构
采用 EMF 设计的一个很直接的好处是,系统可以自动的根据模型生成代码,同时实现了 UML 模型,XML Schema, 注释过的 Java 接口表现模型的统一。但在实际环境中,采用 Rational Performance Tester 内置的 DataPool 还是有很多不太方便的地方,比如:
1) 要经常对文件中的数据进行变化,然后再重新测试时
很多时候测试完后,数据就暂时没用了,因为状态已经更新了,为此需要对测试数据进行替换,但在 RPT 目前的这种序列化反序列化的机制中,要实现这一点并不容易,所以体现在界面中的操作实际上是比较繁琐的,表现为:
如果你的变量比较多,还是非常繁琐的,而且不是一种最好的解决办法。
2) 当测试数据很大,比如文件大概 50M 或更多时
这时候内置的机制会产生一些问题,装载数据时比较慢。这在早期的 6.x 版本中经常遇到,但现在 70 有没有这个问题倒是需要看看底层机制是否有更改。
正因为上面的问题,同时还频繁在实际的测试过程中遇到,因此找到一种更好的替代方案对于实际的项目更加迫切,好在 RPT 建立在 TPTP 的架构上,也就意味着建立在纯粹的 Java 的实现机制下,因此提供了让人很方便的插入 Java 代码的方式,使得很多的扩展和增强成为可能。下面我们就来谈谈如何解决这两个问题。
Rational Performance Tester DataPool 的扩展
为了扩展 DataPool 我们决定对这个环节进行重新的设计,原则如下:
经过设计的类图如下:
图 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;// 退出 } }
PoolLoad.java: 传入文件位置,初始化 RPTDataPool
文件只包括一行,就是调用 RPTDataPool 的构造函数:
static RPTDataPool pool1 = new RPTDataPool("c:\\pool1.txt");
getLine.java: 每个 RPT 的 Test 中,在需要数据池前需要插入的代码,用于把当前用户对应的数据池记录通过一行返回给 Test
public String exec(ITestExecutionServices tes, String[] args) { // 调用 PoolLoad 中初始化的 pool1 的 getDataPoolItemLine 的方法返回当前行然后把 line 返回给 Test String line = PoolLoad.pool1.getaDataPoolItemLine(); return line; }
getName.java: 从返回的行中取出需要的字段 ,每个变量对应着一个 get 方法,比如 getName, getPassword 等 。
public String exec(ITestExecutionServices tes, String[] args) { // 从参数中读出记录行到 line StringTokenizer st = new StringTokenizer(line,",");// 转换成 StringTokenizer while (st.hasMoreTokens()) { if (i == index) { // 匹配需要的字段 name = st.nextToken(); // 把相应的字段赋值 break; } i++; }
Rational Performance Tester 对编写脚本的调试
如何调试客户化的 RPT 脚本,因脚本在后端运行时,无法看到任何的控制台
通过将调试信息写入文件的方式 。
首先定义变量: String mess = “begin”;
然后在需要输出的位置,把信息附在 mess 中, 比如: mess = mess +line + "*******\r\n";
在方法调用完后,把 mess 信息输出到文件,如下:
try {
FileWriter outFile = new FileWriter("C:\\response1.txt");
outFile.write(mess);
outFile.close();
} catch (Exception e) {
}
最后直接打开文件,查看相关的内容 。
如果是在 RPT Test 中的代码,可以采用 TPTP 的 Log, 将相关信息输出到执行日志中 。
首先 import IVirtualUserInfo, 主要是为了得到当前的用户 id。
然后调用 ITestExecutionServices 的 getTestLogManager 的 reportMessage 方法,把需要的信息记录到 TPTP Log 中 。 Tes.getTestLogManager().reportMessage(
"name =" + Integer.toString(vui.getUID()) + "==" + name);
调试方式的比较:
在第一种方式下,能直接以文件的方式一目了然所有的输出,但无法看到那个虚拟用户的 id 等信息,这是传统的,大家比较适应的方式。
通过 TPTP Log 的方式,查看起来比较麻烦,需要在执行日志中展开来看每个节点的返回,效率比较低,如果要象第一种方式下以文件的方式,需要用 winrar 解开 .execute 文件 ( 执行日志 ), 然后会看到 EMF 模型实例的序列化的 xmi 文件,然后通过 ultraedit 打开了就可以看到了。
总结
Rational Performance Tester 构建于 Eclipse 的 TPTP 的测试框架 ,它是 Eclipse 的一类项目 (Top Projects)之一,目前仍然在不断的发展,基于 TPTP 的框架,一方面能很方便的采用框架上已经提供的功能,比如 DataPool,TPTP Log 等,另外,因为 TPTP 本身基于 Java 架构,因此完全可以通过 Java 底层的提供的强大的 API 来客户化代码满足各种不同环境下的不同需求,本文就是对数据池进行改造的一个例子。大家在实际的使用过程中也可以采用各种新的 Eclipse 的技术,比如 EMF,BIRT 来对 RPT 进行各种扩展。开放的架构,灵活的扩展方式和丰富的接口,这也就是我们认为的开放的力量吧。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者