从图6.4中,可以很容易地分析出代码行的执行情况,例如第40~45行代码被用红色标记,左侧显示的代码行执行次数为0,说明整个escapeHTML方法没有被调用过。进一步分析可以发现,escapeHTML方法只在两个catch块中被调用,也就是说用例没有测试到异常情况。报告中两个catch语句也被红色标记,执行次数显示为0。其他绿色显示的行号,说明测试用例已经覆盖到该代码,例如第50行代码显示被执行1次。
图6.4 TestCase01源代码级代码覆盖分析报告片段1
为了覆盖异常情况,需要增加测试用例。第一个try/catch作用于第53行代码:
searcher = new IndexSearcher(indexName);
该行代码用于初始化索引查询引擎,指定查询的索引路径。进一步跟进代码发现,只要传入错误的路径,就会抛出异常。首先测试代码要有设置索引路径的能力,我们在MockJSPSearchResult类中增加了setIndexName函数用于设置索引路径。ResultJSPUnitTest增加对应的测试用例。
TestCase02
前置条件:IndexSearcher指向的索引文件不存在。
描述:测试索引路径不存在时的情况。
输入参数:query=hello,maxresults=100,startat=0。
期待结果:搜索结果为空。
代码6.9 TestCase02
1 @Test |
这时再执行Ant脚本,得到的代码覆盖率报告如图6.5所示。可以看出escapeHTML函数的代码已经被全部覆盖。第54~62行catch语句块中的代码也已经被覆盖。整体的代码覆盖率提高到行覆盖82%,分支覆盖63%。
图6.5 TestCase02覆盖分析报告片段
按照这种思路,继续补充测试用例。
TestCase03
前置条件:索引文件存在,IndexSearcher指向该索引文件。
描述:测试request请求中maxresults和startat参数格式非法的情况。
输入参数:query=hello,maxresults="",startat="abcd a"。
期待结果:maxresults和startat采用默认值。
代码6.10 TestCase03
1 @Test 2 public void testIllegalParameter() throws Exception { 3 MockJSPSearchResult jsp = new MockJSPSearchResult(); 4 jsp.searchResult("hello", "", "abcd a"); 5 assertNotNull(jsp.getHits()); 6 assertEquals(50, jsp.getMaxPage()); 7 assertEquals(0, jsp.getStartIndex()); 8 } |
TestCase04
前置条件:索引文件存在,IndexSearcher指向该索引文件。
描述:测试query值为空的情况。
输入参数:query=null,maxresults=100,startat=0。
期待结果:搜索结果为空,抛出ServletException。
代码.6.11 TestCase04
1 @Test(expected=ServletException.class) 2 public void testNullQueryString() throws Exception { 3 MockJSPSearchResult jsp = new MockJSPSearchResult(); 4 jsp.searchResult(null, "100", "0"); 5 assertNull(jsp.getHits()); 6 } |
在第一次运行测试时,JUnit会报空指针异常,原因在于模拟URL请求的RequestMockObject在初始化时会调用URLDecoder进行解码,如果query参数为空,就会出现空指针异常。而在实际环境中,如果提交请求的URL中不包含query参数,就会出现query值为空的情况。为了解决这个问题,RequestMockObject类需要调整加入空值判断。
代码6.12 RequestMockObject.java——加入空值判断
1 public RequestMockObject(String query, String maxresults, String startat) { 2 if (query != null) 3 this.query = URLDecoder.decode(query); 4 if (maxresults != null) 5 this.maxresults = URLDecoder.decode(maxresults); 6 if (startat != null) 7 this.startat = URLDecoder.decode(startat); 8 } |
TestCase05
前置条件:索引文件存在,IndexSearcher指向该索引文件。
描述:测试query格式非法导致QueryParser异常的情况。
输入参数:query=\,maxresults=100,startat=0。
期待结果:搜索结果为空。
代码6.13 TestCase05
1 @Test 2 public void testParseException() throws Exception { 3 MockJSPSearchResult jsp = new MockJSPSearchResult(); 4 jsp.searchResult("\\", "100", "0"); 5 assertNull(jsp.getHits()); 6 } |