Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3334394
  • 博文数量: 530
  • 博客积分: 13360
  • 博客等级: 上将
  • 技术积分: 5473
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-13 13:32
文章分类

全部博文(530)

文章存档

2017年(1)

2015年(2)

2013年(24)

2012年(20)

2011年(97)

2010年(240)

2009年(117)

2008年(12)

2007年(8)

2006年(9)

分类: Java

2010-09-28 15:01:32

1.单元测试中遇到的问题
      1.程序运行是否正确?
      2. 程序多线程下正确性如何?
      3. 如何测试程序的性能?
      4. 当有多个方案可以选择时,技术上如何比较不同方案的性能?
      对于第1种情况,junit就可以满足需求,对于2,3,4种情况,就必须采用多线程并发测试并进行分析。

2.Punit概述
       p-unit 是一款开放源码的性能测试框架,和 JUnit 不同,JUnit 关注的是测试案例的正确性,而 p-unit 不仅关注测试案例的正确性,还收集测试案例的性能参数,默认情况下,p-unit 收集测试案例的时间和内存消耗情况,可以产生文件,图片,和 PDF 格式的报表。此外,p-unit 还支持参数化测试,多线程测试以及不同 Java 虚拟机性能之间的比较。

3.Punit特点
       *  多线程支持:同一个测试案例可以单线程执行,也可以多线程执行,测试案例开发者只需写一套测试案例。
       * 参数化测试案例:很多测试案例,需要测试同一功能在不同数量级上的性能表现。
       * 不同虚拟机性能测试:只需指定虚拟机路径,即可测试同一个测试案例在不同虚拟机上的表现,报表上可以非常直观显示性能差别。
       * 事件机制构架:punit 是基于事件机制构架的,如果用户想定制报表,只需实现事件响应器,并注册该响应器到 punit 核心即可。

4.punit与junit4
       punit也支持junit4版本,支持的元标签如下
       * @Test(expected = SomeException.class, checkMethod = "someMethod")
       * @Before
       * @After
       * @BeforeClass
       * @AfterClass
       对于junit4,必须在main()中加上
            runner.setConvention(new AnnotationConvention());

5.Check方法
      对于一些测试函数,在执行之前,必须检查一个执行条件是否满足,我们可以通过以"check_"为前缀来定义函数名,比如
      @Test(checkMethod="checkTestAdd")

例子:
private Vector _vector = new Vector();

@Test(checkMethod="checkAdd")
public void testAdd() {
   _vector.add(new Object());
}

public void checkAdd() {
   Assert.areEquals(10, _vector.size());
}

6.单线程执行、多线程执行、多执行嚣执行
单线程执行
       指整个testsuit由一个线程来完成。
       假设现在有两个测试类组成一个testsuit,每个方法睡眠5秒,则整个方法2 * 4 * 5 = 40 秒.

多执行器执行
       指整个testsuit由多个线程来完成。
       假设现在有两个测试类组成一个testsuit,每个方法睡眠5秒,一个线程执行整个方法2 * 4 * 5 = 40 秒. 如果采用多执行器执行,则多个执行器会同时执行testsuit中的多个test类。

public static void main(String[] args) {
   SoloRunner runner = new SoloRunner();
   runner.setExecutorPool(new ExecutorPoolImpl(2));
   runner.run(TestSuite.class);
}

多线程执行
多线程执行是指同一个方法同时多少个线程执行。
多线程执行只需要把SoloRunner转换成ConcurrentRunner即可。
      new SoloRunner().run(MyTest.class);
      new ConcurrentRunner().run(MyTest.class);
默认ConcurrentRunner 建立10个线程执行test方法。可以通过构造函数ConcurrentRunner(int threadCount)设置并发线程数。如果针对不同的方法,需要采用不同的并发线程测试,可以继承Concurrent 接口来实现。

7.TestSuite和Test类
对于TestSuite和Test类,一般调用过程如下
       # 调用 setUp()
       # 调用测试函数
       # 调用tearDown()
注意setUp 和 tearDown的执行时间也被包含到了性能测试中。如果你不想将这段时间统计进去,则需要继承 p-unitTest接口,包括
       # 调用 setUpBeforeWatchers.
       # i调用 setAfterWatchers.
       # 调用 测试方法
       # 调用 tearDownBeforeWatchers.
       # 调用 tearDownAfterWatchers.
你可以将setUp 和 tearDown的代码写到the setUpBeforeWatchers和 tearDownAfterWatchers中。

8.记录时间和内存消费
       punit通过"watcher"来记录内存和时间消耗。punit也支持用户自定义的watcher。用户继承Watcher 接口并注册到punit的runner上即可。时间观察器是默认的。如果需要观察内存消耗,则通过如下代码添加:
                    runner.methodRunner().addWatcher(new MemoryWatcher());

9.Image/PDF 报表
punit除了支持控制台、文本输出方式,也支持image/pdf输出方式。通过添加如下代码即可

Runner runner = new SoloRunner();
// 支持文本输出
runner.addEventListener(new FileLogger());
// 支持对TestSuite的image输出
runner.addEventListener(new TestSuiteReporter(new ImageRender()));
// 支持以image形式的Overview输出
runner.addEventListener(new OverviewReporter(new PDFRender()));


Image/PDF 报表输出有三种粒度- Overview/TestSuite/TestClass.
       # Overview  - 所有的测试数据以一张图输出
       # TestSuite  - 一个testsuite以一张图输出
       # TestClass - 一个test类以一张图输出 
报表文件默认存放在result目录中。

10.参数化测试
      性能测试,不同于单元测试,经常要求测试不同数量级在同一个测试场景中的表现。比如nserting 1000/10000/100000 objects 到 java.util.ArrayList中的性能。
       p-unit 支持将参数传给测试方法,测试案例需要实现 p-unit 的 parameterizable 接口,该接口的主要方法是返回一组参数列表,这组列表的参数将会一一传给测试方法。

public class ParamTestClass implements Parameterized {

    public static void main(String[] args) {
        new SoloRunner().run(ParamTestClass.class);
    }
   
    public Parameter[] parameters() {
        //定义了二个参数实例
        return new Parameter[] { new ParameterImpl(10), new ParameterImpl(20) };
    }

    public void testA(ParameterImpl param) {
        System.out.println("testA count = " + param.count()); //$NON-NLS-1$
        SampleUtil.doSomething();
    }
 
    static class ParameterImpl implements Parameter {
        private int _count;

        ParameterImpl(int count) {
            _count = count;
        }

        public int count() {
            return _count;
        }
       
        public String toString() {
            return String.valueOf(_count);
        }
    }
}
测试结果
testA count = 10
testA(10) - [131.540134ms]
testA count = 20
testA(20) - [297.562446ms]

参考文献
1.punit官方网站 .
2.认识 p-unit : 一款开源的性能测试工具. http://www.ibm.com/developerworks/cn/java/j-lo-punit/




阅读(1732) | 评论(0) | 转发(0) |
0

上一篇:DHT推荐网站

下一篇:java优秀网站

给主人留下些什么吧!~~