JUnit 是名声大燥了,想必只要学过 JAVA 的人都知道世上有个东东叫 JUnit 。记得有个想学 JUnit 的兄弟在群上大喊:我要学 JUnit ,因为 JUnit 应用最广,最好的单元测试工具。无法否认, JUnit 是一个非常让 JAVA 程度员或白盒测试人员喜爱的一个框架。但有时候应用最广的未必就是万能的,最好的未必就是最合适的。
JUnit 也是有缺点的。想象一下,你有一个 web 程序,非常简单的那种,是用 servlet 实现的,你希望对其中的 loginUser () 方法进行单元测试,代码如下:
package com.test.servlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = -5174161414983884806L;
public boolean loginUser (HttpServletRequest request) {
String username = request.getParameter( "username" );
String password = request.getParameter( "password" );
if (username == null || password == null || !username.equals( "cuckoo" )
|| !password.equals( "123" )) {
return false ;
} else {
return true ;
}
}
}
为了能够测试这个方法,你需要得到一个合法的 HttpServletRequest 对象。但不幸的是,你不可能调用 new HttpServletRequest 来创建一个可用的请求。因为 HttpServletRequest 的生命周期是由容器管理的,因此你无法单独使用 JUnit 为 loginUser 方法编写测试类。
此时我们今天的主角就要出来了,它就是 cactus , cactus 是什么?仙人掌吗?呵呵,当然不是了。仙人掌只是它翻译过来的中文名。它如 commons-dbutils , commons-beanutils 等等一样,是 apache 上的一个开源框架。下载地址为 http://jakarta.apache.org/cactus/index.html 或是 http://archive.apache.org/dist/jakarta/cactus/ 用官网是话说, cactus 就是
Cactus is a simple test framework for unit testing server-side java code (Servlets, EJBs, Tag Libs, Filters, ...).
The intent of Cactus is to lower the cost of writing tests for server-side code. It uses JUnit and extends it.
即 Cactus 是一个基于 JUnit 框架的简单测试框架,用来单元测试服务端 Java 代码。 Cactus 框架的主要目标是能够单元测试服务端的使用 Servlet 对象的 Java 方法 httpServletRequest,HttpServletResponse,HttpSession 等。 Cactus 的工作原理在官网上也可以找到,那有详细的说明,以下是其中的一种: 图来自于cactus官网
Cactus provides several TestCase classes that extends the JUnit Testcase and it also provides several kind of redirectors (Servlet Redirector, JSP Redirector, ...). The diagram above is a generic diagram which serves to explain the principles. You'll find details for a specific redirector proxy in the next section. YYYTestCase = ( ServletTestCase | FilterTestCase | JspTestCase ) XXX is the name of the test case. Each YYYTestCase class contains several test cases
这是官网的简单说明,意思是: cactus 提供了几个 TestCase 的类扩展了 JUnit 的 TestCase 的,同时也提供了若干种转向器(重定向程序组件, JSP 的重定向, ...). 上图是一个普通的图,这足以解释的原则。你会发现,在未来一段特定的重定向代理细节。 YYYTestCase = ( ServletTestCase | FilterTestCase | JspTestCase ) XXX 是测试案例的名称。每个 YYYTestCase 类包含几个测试案例。
我们将使用 Cactus 的 ServletTestRedirector 作为上图介绍的 Redirector Proxy ,并使用 Cactus 的 ServletTestRunner 作为执行测试时的 TestRunner ,这两个被撰写为 Servlet ,所以要在 web.xml 中加以定义,代码为:
<? xml version = "1.0" encoding = "UTF-8" ?>
< web-app version = "2.5" xmlns = "http://java.sun.com/xml/ns/javaee"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" >
<!--
<description>cactus test</description>
<display-name>cactusTest</display-name>
-->
< servlet >
< servlet-name > ServletRedirector </ servlet-name >
< servlet-class > org.apache.cactus.server.ServletTestRedirector </ servlet-class >
</ servlet >
< servlet >
< servlet-name > ServletTestRunner </ servlet-name >
< servlet-class > org.apache.cactus.server.runner.ServletTestRunner </ servlet-class >
</ servlet >
< servlet >
< servlet-name > LoginServlet </ servlet-name >
< servlet-class > com.test.servlet.LoginServlet </ servlet-class >
</ servlet >
< servlet-mapping >
< servlet-name > ServletRedirector </ servlet-name >
< url-pattern > /ServletRedirector </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > ServletTestRunner </ servlet-name >
< url-pattern > /ServletTestRunner </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > LoginServlet </ servlet-name >
< url-pattern > / servlet /LoginServlet </ url-pattern >
</ servlet-mapping >
</ web-app >