首先从Httpunit的网站下载Htttp测试框架,解压缩到一个指定的目录。通过Index.htm可以得到英文的指南及示例。
HttpUnit的核心是WebConversation类,其次是WebRequest和WebResponse。通常的用法如下所示。
WebConversation wc = new WebConversation();
WebRequest req = new GetMethodWebRequest( "http://www.meterware.com/testpage.html" );
WebResponse resp = wc.getResponse( req );
首先建立一个WebConversation实例,然后可以通过它建立WebRequest类和WebResponse类的实例,然后通过这两个实例对WEB进行操作。我们来看一个实例,通常如果我们的网站如果更新太快,就可能会存在有些超链没有及时更新的情况。下面的测试就是针对这种情况做的一个测试类,它可以报告从一个HTML网页开始所涉及的超链是否正确。
/*
* Created by IntelliJ IDEA.
* User: champion
* Date: 2002-8-18
* Time: 21:02:35
* To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebLink;
import com.meterware.httpunit.WebResponse;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.util.ArrayList;
public class Testurls extends TestCase {
private WebConversation wc;
private String initurl = "http://localhost/examples/jsp";//需要测试网站的目录或HTML网页名
private String Firsturl = "http://localhost/examples/jsp";//指定的网站,所有不是以这个网站开始的网页都不会测试
private ArrayList urls;
public Testurls(java.lang.String testName) {//构造函数
super(testName);
}
protected void setUp() {//测试前的准备函数,初始化已经测试的网页列表
urls = new ArrayList();
}
protected void tearDown() {//清除数组
urls.clear();
}
public static void main(java.lang.String[] args) {//主测试函数
junit.textui.TestRunner.run(Testurls.class);
}
public static Test suite() {
TestSuite suite = new TestSuite(Testurls.class);
return suite;
}
// Add test methods here, they have to start with 'test' name.
// for example:
public void testHello() {//测试函数,必须用test开头
wc = new WebConversation();//初始化httpunit
assert(this.PrintUrls(initurl,initurl));
}
private boolean PrintUrls(String fromurl,String url) {//私有方法,一个递归函数,用来测试网页超链
String eUrl;
if (url.equals("")) return true;
try {
WebResponse resp = wc.getResponse(url);//返回指定路径的response对象
urls.add(resp.getURL().getProtocol() + "://" + resp.getURL().getHost() +
resp.getURL().getPath());
if (resp.isHTML()) {
WebLink link[] = resp.getLinks();
for (int i = 0; i < link.length; i++) {
WebLink elink = link[i];
eUrl = elink.getURLString();
eUrl = EncodeUrl(eUrl, resp);//格式化URL
if (isThisWeb(eUrl)) { //如果是本站点的 ,就继续
if (!urls.contains(eUrl)) {//如果没有访问过
System.out.println(eUrl);
assert(PrintUrls(url,eUrl));
}
}
}
}
return true;
} catch (Exception e) {
System.err.println(e+" link from url "+ fromurl);
return true;
}
}
private boolean isThisWeb(String url) {//返回是否是属于本网站的网页
return url.indexOf(Firsturl) >= 0;
}
private String EncodeUrl(String sUrl, WebResponse resp) {//把相对路径转为绝对路径。
String dUrl = "";
//如果返回到根目录
if (sUrl.startsWith("/") || sUrl.startsWith("//")) dUrl = resp.getURL().getProtocol() + "://" + resp.getURL().getHost() + sUrl;
//如果是相对路径
if (sUrl.indexOf("http") < 0)
dUrl = resp.getURL().getProtocol() + "://" + resp.getURL().getHost() +
resp.getURL().getPath().substring(0, resp.getURL().getPath().lastIndexOf("/") + 1) + sUrl;
if (sUrl.indexOf("clr.html") > 0) {
System.out.println(dUrl);
System.out.println(sUrl);
}
//如果路径中有父目录, 则转成绝对路径。
if (dUrl.indexOf("..") > 0) dUrl = dUrl.substring(0, dUrl.lastIndexOf("/", dUrl.indexOf("..") - 2)) + dUrl.substring(dUrl.indexOf("..") + 2);
if (dUrl.equals("")) dUrl = sUrl;
return dUrl;
}
}
用这个类测试了一下Tomcat的examples/jsp目录,就发现了有两个超链错误
com.meterware.httpunit.HttpNotFoundException: Error on HTTP request: 404 Not found [http://localhost/examples/jsp/mail/snoop.jsp] link from url http://localhost/examples/jsp/mail/sendmail.html
在sendmail.html中无法访问到snoop.jsp
com.meterware.httpunit.HttpNotFoundException: Error on HTTP request: 404 Not found [http://localhost/examples/jsp/colors/clr.html.html] link from url http://localhost/examples/jsp
从http://localhost/examples/jsp/index.html中无法访问http://localhost/examples/jsp/colors/clr.html.html
上面这个例子只是对网页单纯的访问,这可体现不出HttpUnit的强大功能。下面我们再看一个例子,看看HttpUnit怎么与网页进行交互的, 在Tomcat的examples中有一个numguess的游戏,我们就以它为示例。numguess是猜1到100的一个数字,如果猜小了,网页会提示再猜一个大一点的数字,如果猜大了,就会提示猜小一点的数字。直到猜正确为止。这是通过form以get方式进行的过程。我们的测试代码就是做一个自动猜数的程序,它可以与网站进行交互,直到猜出正确的数字。下面是源代码
/*
* Created by IntelliJ IDEA.
* User: champion
* Date: 2002-8-19
* Time: 8:18:46
* To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
import junit.framework.Test;
import junit.framework.TestSuite;
import junit.framework.TestCase;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebRequest;
import java.util.Random;
public class Testnumguess extends TestCase {
private WebConversation wc;
private String url = "http://localhost/examples/jsp/num/numguess.jsp";
public Testnumguess(java.lang.String testName) {
super(testName);
}
protected void setUp() {
wc = new WebConversation();
}
protected void tearDown() {
}
public static void main(java.lang.String[] args) {
junit.textui.TestRunner.run(Testnumguess.class);
}
public static Test suite() {
TestSuite suite = new TestSuite(Testnumguess.class);
return suite;
}
// Add test methods here, they have to start with 'test' name.
// for example:
public void testGame() {
int i ,oldhigh = 100,oldlow = 1,temp;
boolean isSuccess = false;
int Times = 1;
try {
i = (new Random()).nextInt(100);
WebResponse resp = wc.getResponse(url);
WebForm forms[] = resp.getForms();
WebRequest request = forms[0].getRequest();
while (!isSuccess) {
System.out.println("value=" + i + " you guess " + Times + " Times ");
request.setParameter("guess", String.valueOf(i));
resp = wc.getResponse(request);
forms = resp.getForms();
//request = forms[0].getRequest();
if (resp.getText().indexOf("Congratulations") > 0)
isSuccess = true;
else if (resp.getText().indexOf("lower") > 0) {
temp = oldlow;
oldhigh = i;
i = (i + temp) / 2;
} else if (resp.getText().indexOf("higher") > 0) {
temp = oldhigh;
oldlow = i;
i = (i + temp) / 2;
}
// System.out.print(resp.getText()); //打印当前网页
Times++;
}
assert(isSuccess);
} catch (Exception e) {
System.err.println(e);
}
}
}
得到的运行结果
value=89 you guess 1 Times
value=45 you guess 2 Times
value=67 you guess 3 Times
value=56 you guess 4 Times
value=50 you guess 5 Times
value=47 you guess 6 Times
value=48 you guess 7 Times
Time: 1.031
OK (1 tests)
表示第一次猜89,第二次猜45,直到最后猜到48为正确结果。而交互的核心代码只有三句
request.setParameter("guess", String.valueOf(i));
resp = wc.getResponse(request);
forms = resp.getForms();
setParameter可以设置一个参数的值,然后用resp = wc.getResponse(request);把设置完成的网页传送到服务端,就象我们手工在网页上填写内容,并按提交按钮送到服务端一样。