在开发J2EE Web项目时,测试过程常涉及到代码与Web Container的整合测试。测试过程通常分为:开发、部署、测试、修改四个环节。其中部署环节繁琐,大大降低了测试效率。
这里介绍使用Cactus+Jetty的测试方法,以期缩短部署环节,提高整体测试及开发效率。本文内容建构于Vincent Massol的《JUnit In Action》(Manning 2004)、网友Blog以及自己的实践。
Cactus 是Apache 基金会的开源项目之一,是JUnit测试在Web 应用方面的扩展。其官方文档称其功能可以涵盖主要的三类测试框架,包括:单元逻辑测试、整合单元测试及功能单元测试,其主要用途集中与J2EE环境下的整合单元测试(见: http://jakarta.apache.org/cactus/)。
使用过Eclipse的朋友一定体验过在Eclipse环境下使用JUnit的方便。Cactus是对JUnit的扩展,在Eclipse环境下的界面和JUnit框架一致,所以如果你熟悉JUnit界面,使用Cactus也很容易。
Jetty是一款纯Java开发的Web 应用服务器,这点和tomcat相似。但Jetty比tomcat使用更方便,可以嵌入代码中,以编程式的方式手动启动。这就免去了使用者手工启动Web服务的麻烦,为全自动测试提供了基础(关于Jetty 可从 http://docs.codehaus.org/display/JETTY
获取更详细的信息)。
现在开始测试框架的搭建。
一.创建测试项目
首先打开Eclipse,创建一个新的Web项目。如果存在已有的Web项目,步骤也大致相同。
为了首先测试代码与业务代码的分离,我的项目接受了JUnit In Action中的建议,采用“分离但等同”的目录结构,既测试类和被测试代码在同一个包内,却分到不同的目录中。这样做的好处在于,如果项目开发完成,可以很快的从项目中分离测试代码,加快发布速度。
在这里,我创建了一个新的Source Folder test来存放测试类文件,系统自建的src目录存放被测试代码。
另外,为了能够使用Cactus及Jetty框架,需要将相应的库文件导入项目的库中。具体步骤如下:
1. 导入以下jar包:
junit-3.8.1.jar (JUint 类库)
aspectjrt-1.2.1.jar
cactus-1.7.2.jar
(Cactus 主要类库)
commons-httpclient-2.0.2.jar
commons-logging-1.0.4.jar
org.mortbay.jetty-4.2.17.jar
(Jetty 的主要类库,建议使用cactus提供的,笔者曾经尝试过最新的Jetty 6.1 但没有整合成功)
servletapi-2.3.jar
(支持 J2EE Servlet 库文件)
到项目的WEB-INF/lib/下。
注意,根据所使用版本Cactus及JUnit的版本不同,文件命会有相应的不同。
2. 在Eclipse中刷新项目。
具体生成后的目录结构如下:
二.创建Servlet类及测试类
1.在src/defaultpackage中,创建被测试的servlet类SampleServlet:
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
public class SampleServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public void saveToSession(HttpServletRequest request) {
String testparam = request.getParameter("testparam");
request.getSession().setAttribute("testAttribute", testparam);
}
}
2. 在test/defaultpackage中,创建测试类ServletTestCase:
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.cactus.ServletTestCase;
import org.apache.cactus.WebRequest;
import org.apache.cactus.extension.jetty.JettyTestSetup;
public class TestSampleServlet extends ServletTestCase {
public TestSampleServlet(String theName) {
super(theName);
}
public static Test suite() {
System.setProperty("cactus.contextURL",
"http://localhost:8081/Cactus");
TestSuite suite = new TestSuite();
suite.addTestSuite(TestSampleServlet.class);
return new JettyTestSetup(suite);
}
public void beginSaveToSessionOK(WebRequest webRequest) {
webRequest.addParameter("testparam", "it works!");
}
public void testSaveToSessionOK() {
SampleServlet servlet = new SampleServlet();
servlet.saveToSession(request);
assertEquals("it works!", session.getAttribute("testAttribute"));
}
}
注意其中“System.setProperty("cactus.contextURL",
"http://localhost:8081/Cactus");”语句,该语句设置了Cactus启动Jetty服务器时,jetty服务器所开设服务的URL。这个值就是web服务供外界访问的URL地址。另外,这个值也可以通过Eclipse设置JUnit启动参数的方法设置,在此不再赘述。
三.测试
在Eclipse中运行JUnit。
查看输出结果:
及输出日志:
好了,这个简单的例子就讲到这里。随着对Web测试研究的深入,我会发布更多的文章和大家一起探讨。
下附参考文献:
Vincent Massol,《JUnit In Action》(Manning 2004)
http://jakarta.apache.org/cactus/,关于cactus项目的文档及下载
http://docs.codehaus.org/display/JETTY/ 上有关于Jetty的相关信息
测试用例代码源于网络