开发人员可以使用 assumeThat 并配合 hamcrest 的匹配符 Matcher,对即将被传入到单元测试用例函数中的 runtime 变量值做精确的假设,如果假设不正确(即当前 runtime 变量的取值不满足所假设的条件),则不会将该变量传给该测试用例中假设后面的语句,即程序会从该 assumeThat 所在的 @Test 测试函数中直接自动跳出(test automatically quietly passes,values that violate assumptions are quietly ignored),去执行下一个 @Test 函数,使得本来会中断的测试现在不会中断。
使用假设机制必须得注意以下几点:
由于 JUnit 4.4 引用了 Hamcrest 匹配符库,所以使用 assumeThat 可以编写所有的假设语句。但是为了方便使用,JUnit 4.4 除 assumeThat 之外,还提供了 assumeTrue,assumeNotNull 和 assumeNoException 语句。 要使用 assume* 假设语句,必须得 import static org.junit.Assume.*;。 如果引用了第三方 hamcrest 的匹配符库,必须得 import static org.hamcrest.Matchers.*;,如果引用 JUnit 4.4 自带的匹配符库,需要 import static org.hamcrest.CoreMatchers.*;。
清单 8 假设机制使用举例
例1:
@Test
public void filenameIncludesString() {
//如果文件分隔符不是’/’(forward slash),则不执行assertThat断言测试,直接跳过该测试用例函数
assumeThat(File.separatorChar, is('/'));
//判断文件名fileName是否含有字符串"developerWorks"
assertThat( fileName, containsString( "developerWorks" ) );
}
例2:
@Test
public void filenameIncludesString() {
//bugFixed不是JUnit4.4的函数,是开发人员自己工程中定义的函数,表示判断指定的defect是否
//被修正了,如果被修正,则返回true,否则返回false。这里假设缺陷13356被修正后才进行余下单元测试
assumeTrue( bugFixed("13356") );
//判断文件名fileName是否含有字符串"developerWorks"
assertThat( fileName, containsString( "developerWorks" ) );
}
理论机制(Theory)
为什么要引用理论机制(Theory)
当今软件开发中,测试驱动开发(TDD — Test-driven development)越发流行。为什么 TDD 会如此流行呢?因为它确实拥有很多优点,它允许开发人员通过简单的例子来指定和表明他们代码的行为意图。
TDD 的优点:
使得开发人员对即将编写的软件任务具有更清晰的认识,使得他们在思考如何编写代码之前先仔细思考如何设计软件。 对测试开发人员所实现的代码提供了快速和自动化的支持。 提供了一系列可以重用的回归测试用例(regression test case),这些测试用例可以用来检测未来添加的新代码是否改变了以前系统定义的行为(测试代码兼容性)。
然而,TDD 也同样具有一定的局限性。对于开发人员来说,只用一些具体有限的简单例子来表达程序的行为往往远远不够。有很多代码行为可以很容易而且精确的用语言来描述,却很难用一些简单的例子来表达清楚,因为他们需要大量的甚至无限的具体例子才可以达到被描述清楚的目的,而且有时有限的例子根本不能覆盖所有的代码行为。
以下列出的代码行为反映了 TDD 的局限性:
将十进制整数转换成罗马数字,然后再将其转换回十进制数,并保持原有的数值。(需要大量的测试用例,有限的测试数据可能测不出所实现的代码的错误)。 对一个对象进行操作,希望结果仍然等于原来的对象。(需要考虑各种各样类型的对象) 在任何一个货币的 collection 中添加一个对象 dollar,需要产生出另外一个新的与以前不同的 collection 。(需要考虑所有的 collection 类型的对象)。
理论(Theory)的出现是为了解决 TDD 这个问题。 TDD 为组织规划开发流程提供了一个方法,先用一些具体的例子(测试用例 test case)来描述系统代码的行为,然后再将这些行为用代码语句进行概括性的总的陈述(代码实现 implementation)。而 Theory 是对传统的 TDD 进行一个延伸和扩展,它使得开发人员从开始的定义测试用例的阶段可以通过参数集(理论上是无限个参数)对代码行为进行概括性的总的陈述,我们叫这些陈述为理论。理论是对那些需要无穷个测试用例才能正确描述的代码行为的概括性陈述。结合理论(Theory)和测试一起,可以轻松的描述代码的行为并发现 BUG .开发人员都知道他们代码所想要实现的概括性的总的目的,理论使得他们只需要在一个地方可以快速的指定这些目的,而不要将这些目的翻译成大量的独立的测试用例。