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

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

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

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

分享:

  代码6.4  ResultJSPTest.java代码片段


01 package book.lucene;
02 
03 import static org.junit.Assert.*;
04 
05 import org.junit.*;
06 import java.net.URL;
07 import com.gargoylesoftware.htmlunit.WebClient;
08 import com.gargoylesoftware.htmlunit.html.HtmlForm;
09 import com.gargoylesoftware.htmlunit.html.HtmlPage;
10 import com.gargoylesoftware.htmlunit.html.HtmlTable;
11 
12 public class ResultJSPTest {
13  private static WebClient webClient;
14 
15  private static HtmlPage page;
16 
17  @BeforeClass
18  public static void setUp() throws Exception {
19   webClient = new WebClient();
20  }
21 
22  @Test
23  public void testContent() throws Exception {
24   String[] documentArray = {
25     "Apache Lucene - Building and Installing the Basic Demo",
26     "Apache Lucene - Query Parser Syntax",
27     "Apache Lucene - Scoring" };
28   String[] summaryArray = {
29     "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",
30     "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",
31     "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"
32   };
33   
34   URL url = new URL(
35  "http://localhost:8080/luceneweb/results.jsp?query=hello+ world&maxresults=   100&startat=0");
36   
37   page = (HtmlPage) webClient.getPage(url);
38   HtmlTable table = (HtmlTable) page.getFirstByXPath("//table");
39   assertNotNull(table);
40   for (int i = 0; i < 3; i++) {
41    assertEquals(documentArray[i], table.getCellAt(i+1, 0).as Text());
42    assertEquals(summaryArray[i], table.getCellAt(i+1, 1).as Text());
43   }
44  }
45 
46 }

  第24~32行,定义documentArray和summaryArray数组存放期待的结果,documentArray中存放的是result.jsp页面中Document一栏的内容,summaryArray中存放的是result.jsp页面中Summary一栏中的内容。这里可以用数据文件或参数化列表代替。
  第34~35行,生成URL对象发送请求,URL中的查询条件是“hello world”,分页设置为100条每页,从第0条记录开始。
  第38行,因为result.jsp页面布局非常简单,只有一个table。这里调用getFirstByXPath直接根据table标签定位到搜索结果列表,并封装成HtmlTable对象。
  第39行,先判断列表是否存在。
  第40行,进一步判断列表中的每个单元格的值与期待结果是否一致。
  这里的测试用例中URL是固定的,期待结果也是固定的,可以用Parameter参数化的方式加以改进。在单元测试用例的设计过程中,需要遵循的用例独立以及数据独立的原则。这里的用例与数据采用一一对应的关系,一个等价类总选取一个典型数据。如果需要增加其他类型的数据,例如需要测试query参数为空的情况,其实增加的应该是一条测试用例,该测试用例对应的仍然是固定的URL请求query=&maxresults= 100&startat=0,以及对应的测试结果。这样的设计能够简化测试用例。
  有人会认为这样的设计带来了测试用例的维护成本,改用参数化的方式更加合理。然而经过实践,我们发现其实两者的不同在于维护的对象,固定测试数据的设计将维护的重点放在数据的维护上,而参数化设计的重点放在代码的维护上。更多时候,从整体上看,通过基于数据分离的良好代码结构,让仅维护数据相比较维护代码而言,更加能够适应频繁变更的产品代码。而参数化的设计在动态生成测试数据方面则更具优势。权衡比较,本项目采用了前者的设计方式。
  测试动态代码
  前面的测试方案实际上是将JSP看成是一个黑盒,但result.jsp中含有大量的Java代码。如何进行更细粒度的测试,如何保证JSP代码的覆盖率?这一类的文章很多,但是大多数探讨的是基于JavaBean的测试解决方案。针对本项目这种无Javabean的JSP,我们采用另一种形式的单元测试技巧——环境隔离测试。
  在环境隔离测试中,JSP测试关注的重点在于代码的逻辑。这种思路下,除去嵌入的HTML代码,JSP可以看成是一个纯粹的Java类,不过额外完成了Servlet需要处理的工作。额外的工作与JSP代码逻辑本身关联很小,完全可以剥离。剥离出来的代码如下:
  代码6.5  MockJSPSearchResult.java

001 package book.lucene;
002 
003 import java.net.URLEncoder;
004 import javax.servlet.ServletException;
005 import org.apache.lucene.analysis.Analyzer;
006 import org.apache.lucene.analysis.standard.StandardAnalyzer;
007 import org.apache.lucene.document.Document;
008 import org.apache.lucene.queryParser.ParseException;
009 import org.apache.lucene.queryParser.QueryParser;
010 import org.apache.lucene.search.Hits;
011 import org.apache.lucene.search.IndexSearcher;
012 import org.apache.lucene.search.Query;
013 
014 public class MockJSPSearchResult {
015  private RequestMockObject request;
016 
017  private boolean error = false;
018 
019  private int startindex = 0;
020 
021  private int maxpage = 50;
022 
023  private int thispage = 0;
024 
025  private Hits hits = null;
026 
027  private String indexName = "/opt/lucene/index";
028 
029  private IndexSearcher searcher = null;
030 
031  private String startVal = null;
032 
033  private Query query = null;
034 
035  private String queryString = null;
036 
037  private String maxresults = null;
038 
039  public String escapeHTML(String s) {
040   s = s.replaceAll("&", "&amp;");
041   s = s.replaceAll("<", "&lt;");
042   s = s.replaceAll(">", "&gt;");
043   s = s.replaceAll("\"", "&quot;");
044   s = s.replaceAll("'", "&apos;");
045   return s;
046  }
047 
048  public void searchResult(String _query, String _maxresults, String _startat)
049    throws Exception {
050   request = new RequestMockObject(_query, _maxresults, _startat);
051 
052   try {
053    searcher = new IndexSearcher(indexName);
054   } catch (Exception e) {
055    System.out.println("%>");
056    System.out.println("<p>ERROR opening the Index - contact sysadmin!
057      </p>");
058    System.out.println("<p>Error message: <%="
059      + escapeHTML(e.getMessage()) + "%></p>");
060    System.out.println("<%");
061    error = true;
062   }
063   System.out.println("%>");
064   System.out.println("<%");
065   if (error == false) {
066    queryString = request.getParameter("query");
067    startVal = request.getParameter("startat");
068    maxresults = request.getParameter("maxresults");
069    try {
070     maxpage = Integer.parseInt(maxresults);
071     startindex = Integer.parseInt(startVal);
072    } catch (Exception e) {
073    }
074 
075    if (queryString == null)
076     throw new ServletException("no query " + "specified");
077 
078    Analyzer analyzer = new StandardAnalyzer();
079    try {
080     QueryParser qp = new QueryParser("contents", analyzer);
081     query = qp.parse(queryString);
082    } catch (ParseException e) {
083     System.out.println("%>");
084     System.out.println("<p>Error while parsing query:
085       <%=escapeHTML("
086         + e.getMessage() + ")%></p>");
087     System.out.println("<%");
088     error = true;
089    }
090   }
091   System.out.println("%>");
092   System.out.println("<%");
093   if (error == false && searcher != null) {
094    thispage = maxpage;
095    hits = searcher.search(query);
096    if (hits.length() == 0) {
097     System.out.println("%>");
098     System.out.println("<p> I'm sorry I couldn't
099       find what you were looking for. </p>");
100     System.out.println("<%");
101     error = true;
102    }
103   }
104 
105   if (error == false && searcher != null) {
106    System.out.println("%>");
107    System.out.println("<table>");
108    System.out.println("<tr>");
109    System.out.println("<td>Document</td>");
110    System.out.println("<td>Summary</td>");
111    System.out.println("</tr>");
112    System.out.println("<%");
113 
114    if ((startindex + maxpage) > hits.length()) {
115     thispage = hits.length() - startindex;
116    }
117 
118    for (int i = startindex; i < (thispage + startindex); i++) {
119     System.out.println("%>");
120     System.out.println("<tr>");
121     System.out.println("<%");
122     Document doc = hits.doc(i);
123     String doctitle = doc.get("title");
124     String url = doc.get("path");
125     System.out.println(url);
126     if (url != null && url.startsWith("../webapps/")) {
127      url = url.substring(10);
128     }
129     if ((doctitle == null) || doctitle.equals(""))
130      doctitle = url;
131 
132     System.out.println("%>");
133     System.out.println("<td><a href=\"<%=" + url + "%>\"> <%="
134       + doctitle + "%></a></td>");
135     System.out.println("<td><%=" + doc.get("summary") + "%> </td>");
136     System.out.println("</tr>");
137     System.out.println("<%");
138    }
139    System.out.println("%>");
140    System.out.println("<%");
141    if ((startindex + maxpage) < hits.length()) {
142 
143     String moreurl = "results.jsp?query="
144       + URLEncoder.encode(queryString) + "&amp; maxresults="
145       + maxpage + "&amp;startat=" + (startindex + maxpage);
146     System.out.println("%>");
147     System.out.println("<tr>");
148     System.out.println("<td></td><td><a href=\"<%=" + moreurl
149       + "%>\">More Results>></a></td>");
150     System.out.println("</tr>");
151     System.out.println("<%");
152    }
153    System.out.println("%>");
154    System.out.println("</table>");
155    System.out.println("<%");
156    if (searcher != null)
157     searcher.close();
158    System.out.println("%>");
159   }
160  }
161 }

 

 

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

关注51Testing

联系我们

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

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

沪ICP备05003035号

沪公网安备 31010102002173号