Lucene In Action 中文版 [2]

Lucene In Action 中文版 [2] 包含:
JUnit基础
 
JUnit基础
这部分是对JUnit快速但当然不完整的介绍。我们将提供理解我们示例代码所需的基础知识。
首先,我们的JUnit测试用例继承 junit.framework.TestCase并且很多通过部LiaTestCase基类间接继承它。我们的具体测试类附合这个命名习惯:给类名加后缀Test。例如,我们的QueryParser的测试是QueryParserTest.java。JUnit自动执行所有类似public void testXXX()的方法,此处XXX是个任意有意义的名称。JUnit测试方法必须简洁,保持好的设计。(例如创建可重复的功能模块等等)

断言
JUnit建立在一组assert语句上,使你自由编写简洁的测试代码并使JUnit框架处理失败状态及指出细节。最常用的assert 语句是assertEquals; 一些是为不同的数据类型而重载的
assertEquals方法。一个示例测试方法如下:

public void testExample() {
SomeObject obj = new SomeObject();
assertEqueals(10, obj.someMethod());
}

如果指定的值(在本例中的10)不等于真实值(本例中是调用obj的someMethod的返回值),assert方法抛出运行时异常。除了 assertEquals,为了方便还有一些其他assert方法。我们也使用assertTrue(expression)、assertFalse (expression)和assertNull(expression)语句。这些测试分别判断这个表达式是否是true、false和null。assert语句有个接受一个附加的String参数的重载表示。String参数都是用来汇报的,在测试失败时向开发人员指出更多信息。我们使用这个String消息参数以更好的描述。通过以这种风格编写我们的测试用例,可以从我们构建大系统的复杂中解放出来,而且可以每次只关注更少的细节。利用合适的测试用例,我们能够增强信心和灵活性。信心来自于我们知道代码的变化如优化算法不会破坏系统的其它部分,因为出现这种情况的话,自动测试组件能让我们在它影响产品之前发现。重构是一种改变代码内部结构的艺术(或者说科学),所以它能够适应变化的需求而又不影响系统的对外接口。
在上下文中的JUnit
让我们看一下到目前为止谈论的JUnit并把它放到本书的上下文中。JUnit测试用例继承于junit.framework.TestCase,且测试方法都类似public void testXXX()形式。我们的测试用例之一(第3章)如下:

public class BasicSearchingTest extends LiaTestCase {
public void testTerm() throws Exception {
IndexSearcher searcher = new IndexSearcher(directory);
Term t = new Term(“subject”, “ant”);
Query query = new TermQuery(t);
Hits hits = searcher.search(query);
assertEquals(“JDwA”, 1, hits.length());

//One hit expected for search for “ant”
t = new Term(“subject”, “junit”);
hits = searcher.search(new TermQuery(t));
assertEquals(2, hits.length());
Two hits expected for “junit”
searcher.close();
}
}

当然,我们将在之后解释这个测试用例中使用的Lucene API。现在我们只关注JUnit的细节。testTerm方法中的directory变量没 在此类中定义。JUnit提供一个在执行每个测试方法之前的初始化钩子;这个钩子是名为public void setUp()的方法。我们的 LiaTestCase基类以这种方式实现setUp:

public abstract class LiaTestCase extends TestCase {
private String indexDir = System.getProperty(“index.dir”);
protected Directory directory;
protected void setUp() throws Exception {
directory = FSDirectory.getDirectory(indexDir, false);
}
}

如果testTerm中的第一个断言失败,我们会得到一个异常:

junit.framework.AssertionFalsedError: JDwA expected:<1> but was:<0>
at lia.searching.BasicSearchingTest.
→ testTerm(BasicSearchingTest.java:20)

这个失败指出我们的测试数据与预期的结果不同。

测试Lucene
本书中的大部分测试都是测试Lucene本身的。实际上,这是否现实呢?难道要测的不是我们自己写的代码而是库本身?有个 Test Driven Development的姊妹篇是用来学习API的:Test Driven Learning。它为新API写测试以了解它是 如何工作以及你能从中得到什么时非常有帮助。这正是我们在大部分代码示例中所做的,所以测试都是测试Lucene它本身。但是不要把这些为学习而做的测试 抛开。保留它们以确保你在升级到新版的API或因API改变而重构时,它们能够保持真值。

模型对象
在一些用例中,我们使用模型对象来测试。模型对象用来作为探测器传入真实的业务逻辑,以判断这个业务逻辑是否正常工作。例如,第4章中有个 SynonymEngine接口(4.6节)。使用这个接口的真实业务逻辑是个分析器。当我们想测试这个分析器本身时,SynonymEngine使用什 么类型就不重要,我们只想使用一个定义良好并有可预见行为的对象。模型对象可以使得测试用例尽可能简单,这样它们每次只测试系统的一个方面,在测试失败要修正什么错误时没有纠缠的依赖。使用模型对象的一个好处来自于设计的变动,例如关系的分离和设计使用接口代替直接具体实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值