服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

用strutstestcase测试struts应用程序


  一、struts测试概述
  
  一个具有良好系统架构的j2ee应用程序至少有三层组成,即表现层,商业层和系统
  
  集成层(包括数据存取以及和其他系统集成),目前,struts是应用比较广泛,实现mvc2模式应用于表现层的一种技术. 在这里面,struts action主要用来完成一些简单的数据校验,转换,以及流程转发控制(注意:这里流程不是业务规则). 因此在对整个应用程序进行测试时,我们同时也要测试struts action.
  
  但是,测试struts action相对测试简单的javabean是比较困难,因为struts是运行在web服务器中, 因此要测试struts action就必须发布应用程序然后才能测试. 我们想象一下,对于一个拥有上千个jsp page和数百甚至数千java classes的大规模应用程序,要把他们发布到诸如weblogic之类的应用服务器再测试,需要多少的时间和硬件资源? 所以这种模式的测试是非常费时费力的.
  
  所以,如果有一种办法能够不用发布应用程序,不需要web服务器就能象测试普通java class一样测试struts action,那就能极大地加强struts的可测试性能,使应用程序测试更为容易,简单快速. 现在这个工具来了,这就是strutstestcase.
  
  二、strutstestcase 概述
  
  strutstestcase 是一个功能强大且容易使用的struts action开源测试工具,它本身就是在大名鼎鼎的junit基础上发展起来的。因此通过和junit结合使用能极大加强应用程序的测试并加快应用程序的开发.
  
  strutstestcase提供了两者测试方式,模仿方式和容器测试方式. 所谓模仿方式就是有strutstestcase本身来模拟web服务器. 而容器测试方式则需要web服务器. 本文要讨论的是前者,原因很简单,不需要web服务器就能象测试普通的java class一样测试struts action.
  
  三、准备strutstestcase和struts action/actionform/config
  
  strutstestcase是一个开源工具,可以到http://strutstestcase.sourceforge.net下载. 目前最新版本是2.1.3,
  
  如果你使用servlet2.3就下载strutstestcase213-2.3.jar,使用servlet2.4的就下载strutstestcase213-2.4.jar.
  
  另外strutstestcase本身就是从junit继承的,所以你还需要下载junit3.8.1.
  
  在本文中,我们用一个简单的例子来做测试. 假设我们有一张表hotline(country varchar2(50),pno varchar2(50)),
  
  我们要做的是根据输入条件从这张表检索相应的记录.检索条件是country.
  
  value object:
  package sample;
  public class hotlinedto implements serializable{
  private string country = "";
  private string pno = "";
  /**
  * method hotlineactionform
  *
  *
  */
  public hotlinedto () {
  super();
  }
  public void setcountry(string country) {
  this.country = country;
  }
  public void setpno(string pno) {
  this.pno = pno;
  }
  public string getcountry() {
  return (this.country);
  }
  public string getpno() {
  return (this.pno);
  }
  }
  
  actionform:
  package sample;
  import org.apache.struts.action.actionform;
  public class hotlineactionform extends actionform{
  private string country = "";
  private string pno = "";
  /**
  * method hotlineactionform
  *
  *
  */
  public hotlineactionform() {
  super();
  }
  public void setcountry(string country) {
  this.country = country;
  }
  public void setpno(string pno) {
  this.pno = pno;
  }
  public string getcountry() {
  return (this.country);
  }
  public string getpno() {
  return (this.pno);
  }
  }
  
  action class:
  public class searchhotlineaction extends action {
  public actionforward execute(actionmapping mapping, actionform form, httpservletrequest request,
  httpservletresponse response) throws exception {
  string target = "";
  try{
  //调用hotlinedao检索hotline
  string country=((hotlineactionform)form).getcountry();
  list hotlinelist = hotlinedao.gethotlinelist(country);
  if(hotlinelist!=null && hotlinelist.size()>0){
  request.setattribute("hotlinelist",hotlinelist);
  target = "hotlinelist";
  }else{
  target = "notfound";
  }
  }catch(exception ex){
  ....
  }
  }
  
  struts config:
  <struts-config>
  <form-beans>
  <form-bean name="hotlineactionform" type="sample.hotlineactionform" />
  .......  </form-beans> <action-mappings>
  <action path="/searchhotline"
  name="hotlineactionform"
  type="sample.searchhotlineaction "
  scope="request"
  validate="false">
  <forward name="hotlinelist" path="/hotlinelist.jsp"/>
  <forward name="notfound" path="/searchhotline.jsp"/>
  </action>
  .....
  <action-mappings>
  ........ <struts-config>
  
  四、初试strutstestcase
  
  当采用模拟方式时,所有的strutstestcase测试class都是从mockstrutstestcase继承下来的.
  
  下面我们就创建一个最简单的测试class.
  public class searchhotlineaction extends mockstrutstestcase {
  public void setup()throws exception{
  }
  public void teardown()throws exception{
  }
  public void testsearchhotline() throws exception{
  setrequestpathinfo("/searchhotline.do");
  addrequestparameter("country", "cn");
  actionperform();
  }
  }
  
  上面的class相信用过junit的朋友都很熟悉.
  
  好了,一个简单的测试例子就完成了,如果你用的是eclipse就选择run-run...-junit-new就可以直接运行.不需要发布你的程序,不需要任何的web服务器支持,就可以测试struts action,这就是strutstestcase带来的好处.下面简单地介绍一下它是怎么工作的.
  
  在上面的例子中,我们调用setrequestpathinfo()告诉strutstestcase我们要模拟jsp调用searchhotline.do这个action,并且调用addrequestparameter()增加了一个参数country.最后调用actionperform()运行.
  
  看到这里,大家发现一个问题没有? 在上面action的源代码里我们是通过
  
  string country=((hotlineactionform)form).getcountry();
  
  也就是actionform来取得输入的参数值,可我们在testsearchhotline()方法里并没有设置actionform?
  
  那么它是怎么出来的呢? 其实大家如果熟悉struts的运行流程的话就知道,jsp接受用户的输入并发请求时都是类似这样的http://hostname/servletname?param1=value1¶m2=value2. 只是struts接受到这些参数后再根据struts config里的action和actionform的映射把他们转为actionform后传给action的.
  
  在上面的例子,我们只是简单地运行了action,那么action是否正确执行以及返回的结果是不是我们想要的呢?
  
  我们继续完善一下testsearchhotline()这个method.
  
  public void testsearchhotline() throws exception{
  setrequestpathinfo("/searchhotline.do");
  addrequestparameter("country", "cn");
  actionperform();
  verifynoactionerrors();
  verifyforward("hotlinelist");
  assertnotnull(request.getattribute("hotlinelist"));
  list hotlinelist = (list) request.getattribute("hotlinelist");
  for (iterator it = hotlinelist.iterator();it.hasnext();){
  ....
  }
  }
  
  我们在actionperform()后增加了几行语句来断定struts action是否正确执行.
  
  verifynoactionerrors() -- 判断action里没有任何的action;
  verifyforward("hotlinelist") -- 判断action确实转发到hotlinelist;
  assertnotnull(request.getattribute("hotlinelist")) -- 判断action确实返回了hotlinelist并且不为空
  
  到这里,我们已经基本上讨论完了strutstestcase的核心部分. 从头到尾,我们没有发布应用程序,也不需要web服务器,对我们来讲,struts action就象普通的java class一样容易调试测试.这就是strutstestcase给我们带来的方便.
  
  五、深入strutstestcase
  
  除了以上我们用到的几个断定和校验方法外,strutstestcase还提供了其他几个方法便于我们测试struts action. 下面我一一讲述,具体的大家可以参考文档.
  
  verifyactionerrors/messages -- 校验actionactionservlet controller 是否发送了actionerror或actionmessage.  参数为actionerror/message key
  verifynoactionerrors/messages --校验actionactionservlet controller 没有发送actionerror或actionmessage
  verifyforward -- 校验action是否正确转发到指定的actionforward.
  verifyforwardpath -- 校验action是否正确转发到指定的url
  verifyinputforward -- 校验action是否转发到action mapping里的input属性
  verifytilesforward/verifyinputtilesforward--和以上类似,应用程序使用到tiles时用的
  
  六、关于web.xml和struts-config.xml
  
  缺省情况下,strutstestcase认为你的web.xml和struts-config.xml的路径分别是:
  /web-inf/web.xml和/web-inf/struts-config.xml
  
  1. 假如你的web.xml/struts-config.xml的路径是d:/app/web/web-inf/web.xml(struts-config.xml)的话,就需要把d:/app/web加到classpath.
  
  2. 假如你的struts config是strust-config-module.xml,那么必须调用setconfigfile()设置你的struts config文件
  
  七、结束语
  
  j2ee应用程序的测试在开发过程中占有相当重要的位置,利用strutstestcase能极大方便你测试基于struts的应用程序.

扫描关注微信公众号