关闭

51Testing丛书连载:(八) 互联网单元测试及实践

发表于:2008-8-14 17:44

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:陈卫俊 赵璨 周磊等    来源:51Testing软件测试网

  这段代码将HTML标签改为System.out.println语句输出。MockJSPSearchResult类有两个方法,escapeHTML方法对应result.jsp中的escapeHTML方法,searchResult方法封装了result.jsp中除escapeHTML外的所有代码逻辑。因为JSP需要处理URL请求,所以需要一个MockObject类来模拟URL请求,在代码的第50行由初始化的RequestMockObject对象完成。代码6.6为此对象的代码。

  代码6.6  RequestMockObject.java


01 package book.lucene;
02 
03 import java.net.URLDecoder;
04 
05 public class RequestMockObject {
06  private String query;
07 
08  private String maxresults;
09 
10  private String startat;
11 
12  public RequestMockObject(String query, String maxresults, String startat) {
13   this.query = URLDecoder.decode(query);
14   this.maxresults = URLDecoder.decode(maxresults);
15   this.startat = URLDecoder.decode(startat);
16  }
17 
18  public String getParameter(String param) {
19   if ("query".equalsIgnoreCase(param)) {
20    return this.query;
21   } else if ("maxresults".equalsIgnoreCase(param)) {
22    return this.maxresults;
23   } else if ("startat".equalsIgnoreCase(param)) {
24    return this.startat;
25   } else {
26    return null;
27   }
28  }
29 }

  经过这样的处理后,对JSP的单元测试转换为对熟悉的Java类的单元测试。针对MockJSPSearchResult类,画出对应的流程图,设计测试用例进行路径覆盖。我们略去测试用例的设计分析,关于用例的设计前面已经有介绍。这里我们换一种思路,结合代码覆盖率来完善测试用例。测试代码覆盖率的工具采用Cobertura,关于Cobertura,本章不再做详细介绍。感兴趣的读者可以登录http://cobertura.sourceforge. net/index.html了解。
  先给出第一个测试用例。
  TestCase01
  前置条件:索引文件存在,IndexSearcher指向该索引文件。
  描述:以hello为关键字,使用默认的搜索设置进行搜索。
  输入参数:query=hello,maxresults=100,startat=0。
  期待结果:有2条搜索结果。
  代码6.7  TestCase01

01 package book.lucene;              
02 …                
03 public class ResultJSPUnitTest {
04  @Test
05  public void testSearchResult() throws Exception {
06   String[] documentArray = {
07     "Apache Lucene - Building and Installing the Basic Demo",
08     "Apache Lucene - Query Parser Syntax" };
09   String[] summaryArray = {
10     "Apache > Lucene [Lucene] [Lucene]   Main Wiki Lucene 2.3.1       Documentation   Documentation Overview Javadocs All Core Demo      Contrib Analyzers Ant Bdb Bdb-je Benchmark Highlighter Lucli      Memory Miscellane",
11     "Apache > Lucene [Lucene] [Lucene]   Main Wiki Lucene 2.3.1       Documentation   Documentation Overview Javadocs All Core Demo      Contrib Analyzers Ant Bdb Bdb-je Benchmark Highlighter Lucli      Memory Miscellane" };
12 
13   MockJSPSearchResult jsp = new MockJSPSearchResult();
14   jsp.searchResult("hello", "100", "0");
15   
16   Hits hits = jsp.getHits();
17   assertEquals(2, hits.length());
18   for (int i = 0; i < 2; i++) {
19    assertEquals(documentArray[i], hits.doc(i).get("title"));
20    assertEquals(summaryArray[i], hits.doc(i).get("summary"));
21   }  
22  }
23 }

  这时使用Ant的Cobertura任务,先对编译好的class文件进行插桩,然后运行JUnit测试,最后生成代码覆盖率的报告。下面代码中列出的是Ant的build.xml,代码中列出了覆盖率相关的task,略去了其他内容。
  代码6.8  结合Cobertura任务的Ant脚本

01 <?xml version="1.0" encoding="UTF-8"?>
02 
03 <project name="lucene" default="coverage" basedir=".">
04  ...
05  <taskdef classpathref="cobertura.classpath" resource="tasks. properties" />
06 
07  ...
08  <target name="instrument" depends="compile">
09   <delete file="cobertura.ser" />
10   <delete dir="${instrumented.dir}" />
11 
12   <cobertura-instrument todir="${instrumented.dir}">
13    <ignore regex="org.apache.log4j.*" />
14    <fileset dir="${classes.dir}">
15     <include name="**/*.class" />
16     <exclude name="**/*Test*.class" />
17    </fileset>
18   </cobertura-instrument>
19  </target>
20 
21  ...
22  <target name="junit" depends="compile">
23   <mkdir dir="${target.report.dir}" />
24   <junit printsummary="yes" haltonerror="no" haltonfailure="no" fork="yes">
25    <classpath location="${instrumented.dir}" />
26    <classpath>
27     <pathelement location="${target.classes.dir}" />
28    </classpath>
29    <classpath refid="cobertura.classpath" />
30 
31    <!--list all tests-->
32    <formatter type="plain" usefile="false" />
33    <test name="book.lucene.ResultJSPUnitTest" todir="${target. report. dir}" />
34   </junit>
35  </target>
36 
37  <target name="coverage-report">
38   <cobertura-reportformat="html"datafile="cobertura.ser" destdir= "${coverage. html.dir}">
39    <fileset dir="${src.dir}">
40     <include name="**/*.java" />
41    </fileset>
42   </cobertura-report>
43  </target>
44 
45  <target name="coverage" depends="instrument,junit, coverage-report" />
46 </project>

  第5行,定义了cobertura任务。
  第8~19行,定义了被测代码的插桩任务。首先cobertura会新建一个cobertura.ser数据文件,用于存放对插桩代码进行代码覆盖分析的数据。Cobertura还会对编译后的class文件进行插桩,并将插桩后class文件放入另一个独立目录中。
  第22~35行,运行JUnit测试用例。在classpath中加入插桩后的class目录。
  第37~43行,coverage-report任务根据cobertura.ser生成代码覆盖报告。
  

  定义好build.xml后,执行ant命令完成测试代码的构建。生成的代码覆盖率报告如图6.3所示。

  图6.3  TestCase01代码覆盖率报告
  从报告中可以看出,主要代码MockJSPSearchResult的覆盖率很不理想,行覆盖率只有68%,分支覆盖率只有53%。RequestMockObject代码覆盖率虽然为92%和83%,但是MockObject本身非被测代码,这里重点还是分析MockJSPSearchResult的代码。通过点击报告中MockJSPSearchResult的链接,Cobertura显示了源代码级的覆盖结果,见图6.4。

53/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号