项目中counter打印的几种方法思考
项目中需要在class文件中加入probe(常见是使用静态变量保存),那么在什么时候dump out?
首先由于是测试程序,被测试的程序本身就可能会随时出错,所以该在何处dump profile 信息呢。在由别的程序调用时我们可以用try来捕获所有异常,在finally中收集信息。这就要求是在同一个jvm中。由于java中没有析构函数的说法,而garbage清理对象的时间我们也无法确定。在项目过程中,在命令行和测试底层功能时我是用上述方法解决得。
现在要把profile功能和JUnit结合在一起,这就需要想办法解决这个问题。首先,在eclipse中,一般run一个程序是在新的JVM中的。其次对JUnit的原则来说,一般是一个TestCase(指一个类中多个testXXX方法会被生成一个testcase)只测一个功能。所以在整个过程中,需要dump和clear counter。而我的plugin又是运行在eclipse的这个JVM中,如何在两个JVM中传递信息呢。简单想来,可以在在plugin注册TeseListener,当session,每个testcase动和结束,可以收集到基本信息。但是由于在两个JVM,事实上这是不可以收集到的。在每个TestCase上可以写setUp()和tearDown(),最简单的就是在这个过程中clear和dump。
方法1:在setUp或tearDown中写上clear,dump counter的方法。可以保存到xml文件中。再在session结束时,根据所生成的xml信息进一步处理。
好处:绝对是正确的dump clear counter信息。在这里可以很正确的处理执行顺序的问题。即使监听者能知道testcase start和finish的时间。但是可以明确看到是异步的,就是说一个监听者可能会落后testcase执行。这样的话counter就不准确了。何况其中还存在如何传递counter信息的问题。
缺点: 需要dump counter 然后由plugin重新读入。这需要涉及较慢的文件操作。其次需要user 在写testcase时按特定的格式写。
方法1.1:为了改进user的使用,考虑使用soot或者处理自动加入或者setUp和tearDown。(事实上最简单的处理是使用自己junit.jar包,在TestCase.class中加入,可以通过改变classpath实现)(简单,但是出错后容易迷惑用户)
方法2:eclipse可以设置为run新的程序时于eclipse共享一个JVM,但是eclipse上强烈说明希望不要这样做,因为可能如果程序有问题会造成eclipse崩溃。在此处可以确定不大现实使用这种方法,原因在于需要于JUnit集合,LaunchDelegate只是包装了JUnit的LaunchDelegate,在JUnit的LaunchDelegate明确是新启动JVM,就是因为测试工具当然可能是测试的程序出错。但是JUnit使用safeRunnable来保证测试程序出错不影响JUnit framework崩溃。在我的项目应该没有方法解决这个问题,由于需要集成JUnit。
方法3:使用内存数据库。使用数据库不为是一个好方法。特别是在测试大型程序时收集的数据量是十分巨大的。而我程序处理时使用HashMap来查找单个counter也会造成效率低。这样在插入probe时,可以直接往数据库写数据。当然为解决2个JVM之间传递数据,此数据库应该运行在eclipse plugin的JVM上,这样plugin可以数据库轻易得到数据。或者再要求一个JVM,绝对不该在跑测试的JVM上,我们希望JUnit启动的JVM可以尽快down(是否可以启动多个等等原因还需要验证)。
好处:在eclipse上JVM的数据库可以不用启动的关闭。只要plugin被Launch后可以一直存在。只需要清空操作。使用内存数据库也加快了数据处理速度。并且不需要在testcase的setUp和tearDown中加入任何代码。(????考虑异步和多个profile共存的counter设计),最好的希望就是比规定用户的使用方法,只要用户书写符合JUnit写法,一切由插件在背后完成。
缺点:效率(需要验证可行性)