用 jython 构建 junit 测试包
ReadyGo!技术成就梦想
www.efish.cn
efish
2007-10-24 11:46:54
开发人员有多种理由决定自动化单元测试。许多人甚至进一步发挥它,自动化这些测试的定位和执行。但是如果想要测试装具模块(test harness)像静态定义的那样运行呢?请跟随开发员 michael nadel,看看如何利用 python 模拟静态定义的 junit testsuite 类。
junit 测试框架被越来越多的开发小组所共同使用。归功于各种各样的测试装具模块,现在可以测试构成任何 java 应用程序的几乎每一个组件。事实上,几乎整个二级市场似乎都是用围绕 junit 建立的。包括 cactus、jfcunit、xmlunit、dbunit 和 httpunit 这样的装具模块都可以免费供开发人员用于测试应用程序。随着系统的复杂程度的增加,并且有这么多工具可供使用,没有什么理由不依靠单元测试。
不过,开发人员不仅仅是程序员。我们与用户交互以修复 bug 并确定需求。我们参加会议并进行电话推销。我们完成一些(有时全部)质量保证功能。既然有这么多责任,希望尽可能自动化就是自然而然的了。因为好的团队(除了其他事情外)会进行大量测试,希望自动化不同的开发过程的人常常会对这一领域进行详细研究。
自动化单元测试
有许多种自动化所有项目测试用例的定位和执行的方法。一种解决方案是联合使用 ant 的 junit 任务与嵌入的 fileset 任务。这样就可以包括和排除特定目录中的文件(基于文件名样式)。另一种选择是使用 eclipse 的一个功能,它可以指定所有测试所在的和执行的目录。前一种选择提供了对运行的测试进行过滤的灵活性(并且由于它是一个纯粹的无头(headless)java 应用程序,可以运行在几乎所有地方),后一种选择可以调试“动态”包。是否可以结合这两种方式的强大和灵活性?
有了 python 编程语言的 java 平台实现 —— jython,回答是响亮的“可以!”(如果不熟悉 jython,应当在继续本文之前补充这方面知识,更多信息请参阅后面的 参考资料 )。利用 jython 的强大和优雅,可以维护一个定位文件系统、搜索匹配某种样式的类和动态编译 junit testsuite 类的脚本。这个 testsuite 类像所有其他静态定义的类一样,可以用喜爱的调试程序容易地调试。(在本文中使用的例子假定使用的是 eclipse ide,不过,我在这里描述的技术不用做很多修改就可以用于大多数其他 ide。)
在进行任何设计决定时,必须对所做的选择和决定的影响进行权衡。在这里,为了得到调试动态生成的测试包的能力,必须增加额外的复杂性。不过,这种复杂性被 jython 自身所减轻了:jython 经过很好测试并得到很好的支持,并且是开放源代码的。而且,python 越来越成为面向对象的、平台独立的编程的事实上的标准。出于这两种原因,采用 jython 的风险很少,特别是它提供了这样的好处:在创建和调试动态生成的 junit testsuite 类方面具有无可匹敌的灵活性。
如果是否采用 jython 是主要的考虑,那么即使不使用它也可以在解决原来的问题方面有所进展。不使用 jython 的话,可以用一个 java property 文件存储一组类、目录和包,以在包中加入或者排除测试。不过,如果选择使用 jython,就可以利用整个 python 语言和运行时来解决选择执行哪些测试的问题。python 脚本比 java property 文件灵活得多,它只受限于您的想像力。
利用 jython 与 java 平台的无缝集成可以创建静态定义的、然而是动态构建的 testsuite 类。有大量关于 junit 的教程,不过还是看下面这两行代码作为复习。清单 1 是静态构建 testsuite 类的一个例子(这个例子取自 junit: a cook"s tour,有关它和其他 junit 资源的链接请参阅 参考资料):
清单 1.静态定义 testsuite
public static test suite() {
return new testsuite( moneytest.class );
}
清单 1 表明 testsuite 是由 test 类的类实例组成的。这个装具模块完全利用了这一点。为了分析这个工具的代码,应从 参考资料 中下载本文的示例 jar 文件。这个文档包含两个文件:dynamictestsuite.java 和 getalltests.py,前者是一个用 phthon 脚本动态生成 testsuite 的 junit 测试装具模块,后者是一个搜索匹配特定样式的文件的 python 脚本。dynamictestsuite.java 使用 getalltests.py 构建 testsuite。可以修改 getalltests.py 以更好地适合自己的项目的需要。
了解测试装具模块
代码是如何工作的?首先,指派 getalltests.py 获取一组要执行的 test 类。然后,使用 jython api 将这个列表从 python 运行时环境中提取出来。然后使用 java reflection api 构建在表示 test 类名的列表中的 string 对象的类实例。最后,用 junit api 将 test 添加到 testsuite 中。这四个库的相互配合可以实现您的目标:动态构建的 testsuite 可以像静态定义的那样运行。
看一下清单 2 中的 junit suite 清单。它是一个公开 public static testsuite suite() 方法签名的 testcase。由 junit 框架调用的 suite() 方法调用 gettestsuite(), gettestsuite() 又调用 getclassnamesviajython() 以获取一组 string 对象,其中每一个对象表示一个作为包的一部分的 testcase 类。
清单 2. 动态定义 testsuite
/**
* @return testsuite a test suite containing all our tests (as found by python script)
*/
private testsuite gettestsuite() {
testsuite suite = new testsuite();
// get iterator to class names we"re going to add to our suite
iterator testclassnames = getclassnamesviajython().iterator();
while( testclassnames.hasnext() ) {
string classname = testclassnames.next().tostring();
try {
// construct a class object given the test case class name
class testclass = class.forname( classname );
// add to our suite
suite.addtestsuite( testclass );
system.out.println( "added: " + classname );
}
catch( classnotfoundexception e ) {
stringbuffer warning = new stringbuffer();
warning.append( "warning: class "" ).append( classname ).append( "" not found." );
system.out.println( warning.tostring() );
}
}
return suite;
}
在开始时,要保证设置了正确的系统属性。在内部,jython 将使用 python.home 属性来定位它所需要的文件。最终会调用 getclassnamesviajython() 方法,在这里面会有一些奇妙的事情发生,如在清单 3 中将会看到的。
清单 3. 从 python 运行时提取 java 对象
/**
* get
责任编辑: efish
参与评论
查找更多:
核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级核心java基础j2eexmlj2sej2me问题解决核心技术高级
-
相关文章
junit实施
测试的概念 回归测试框架-junit design by contract refactoring ide对junit的支持 junit简..
用junit框架实现java单元测试
随着软件项目的逐渐增大,软件测试在软件开发中的地位显得越来越重要。如果软件项目没有良好的测试流程,随..
tomcat类加载机制
tomcat server在启动的时候将构造一个classloader树,以保证模块的类库是私有的 tomcat server的classlo..
判断java_home友好提示用户
javalauncherbat.zip 4kb
这个脚本执行后判断 java_home 是不是有效, 如果找不到的话就打开帮助页面指..
如何同时启动多个tomcat服务器
前些时日,出于某种需要,需要同时启动多个tomcat服务器,在网上查了半天,才找到解决的办法,拿出来分享一..
tomcat深入??内部结构描述
tomcat服务器是一种servlet/jsp容器,更实质性的说是servlet容器,因为jsp最终还是被编译成servlet来执行的..
2秒记住本站域名
玩过泡泡龙吗?Readygo?Go! 再加上.Com.Cn的后缀,那就是大名小顶的ReadyGo.com.cn
