最近在maven项目中用Arquillian做单元测试和集成测试,遇到一些小问题,通过看老外的文档算是逐步解决或者绕开了,在此记录一下供以后查阅。
以下是我的感受
1.在基于容器的单元测试中,普通那种Junit测试方法能测的东西实在不多。比如依赖注入,数据库的读写等,如果都通过写Mock来测试的话,代码量太大,而且对tester的要求未免过高了;测试的效果不好保证,完全依赖于tester的代码水平,恐怕成本也不是一般公司能够负担得起的。
2.必要性。呵呵本来这个应该放在地一点。就算仅仅作单元测试,也是提高代码质量的好办法。起码能保证被测试过的方法能够正常工作,或者错误的处理时按照制定的规划完成的,比如web应用,后台某个地方的逻辑有问题,不必再向以前那样完全部署好程序,然后通过界面一步步点进去找问题。
以上这些我想做过这种单元测试的都懂得,下面说说我遇到的问题。
1.jar包引用
如果是一些本地jar包,最好倒入本地仓库或者私服,比如自己写的一些helper类的包;便于管理;有些可以放入应用服务器通用的classpath的路径中,比如数据库驱动。
最初搜到一些文档,作微部署的时候,最简单的做法是:生成空的JavaArchive,然后addClass到这个JavaArchive,最后作为@Deployment方法的结果返回,这样基本上适用于超级简单的ejb测试还比较适合,一旦引用了第三方的包,这样是不能运行的。我的做法是直接生成EnterpriseArchive,这样就可以加入jar,资源文件,class了。如下所示:
@Deployment
public static EnterpriseArchive createEar() {
EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive.class,"mytest.ear");
PomEquippedResolveStage mavenResolver = Maven.resolver().offline().loadPomFromFile("pom.xml");
//log4j
File jarFile = mavenResolver.resolve("log4j:log4j").withoutTransitivity().asSingleFile();
ear.addAsLibraries(jarFile);
//h2数据库
jarFile = mavenResolver.resolve("com.h2database:h2").withoutTransitivity().asSingleFile();
ear.addAsLibraries(jarFile);
return ear;
}
2.测试库的选用
如果说最逼真的测试库,当然是与生产环境一样的库。不过作为单元测试来说,不应该依赖于外部环境。针对那些连不上数据库(比如断网)的异常,可单独使用一些Mock类来完成。
个人认为,h2database是一个非常好的选择,而且支持参数Model,可模拟mysql,db2等数据库的行为,而且可以使用mem的方式进行连接,完全不依赖于外部环境。
3.复杂客户端的测试
根据js框架的不同,可以选择不同的方式。比如jquery,已经被可以使用Graphere直接进行测试了;extjs,目前恐怕不好办,控件id是变化的,而extjs控件加入的原则就是如果不必给出id,就不要给,否则如果id重复会造成2个控件在一起显示的奇怪问题;我基本上实验了多次,最后直接采用测试服务器地址的方法:界面不通过代码来测试,只测试ajax调用的地址来搞。这样的话,我在进行微部署的时候,直接把web工程中代码,描述符等服务器端的东西加载进来就可以了,js,html,图片等就不管了。
同样,最好写需要创建ear的包,然后可以往里增加jar包,war包。