一、为什么测试很重要?
- 塑造系统的设计。我们知道输入和输出应该是什么样的,但是我们需要创建什么对象来做到这一点呢?代码应该塑造成什么样的“形状”?编写测试可以让我们知道应该创建什么样的代码。
- 为了确保初始和持续的正确性。让我们的应用程序如期望地那样运作并且始终如一地精确很重要。测试应该竭力确保做到这一点。
- 文档。测试是系统的文档,因为它会说明它应该做什么以及应该怎么做。
二、给测试命名
尽量避免testXXX,willXXX等名称,像test,will,should等词语都是没有意义的。
测试函数和测试类的名称应该直截了当地显示所测试的内容。
例如
addingNumbersWillSumValuesTogether()
explodesOnNegativeID()
notifiesListenersOnUpdates()
不要害怕表达出来。如果你的测试名称确实需要很长的一串单词,那就这么做,只要它能清楚说明将发生什么事情。
三、测试的三个部分
测试将分为3个部分:设置,操作,断言。
1、设置
对你的测试设置代码应该只与在测试中被断言的值相关。如果你有多余的设置代码,那就会搞不清楚它是什么,并且与测试不相关。
这可以通过多种方式实现:
- 将通用设置移动到使用
@Before
注解的具体设置方法。 - 将重复的设置代码移动到辅助方法
- 使用Maker来创建复杂的测试对象,并只设置测试中相关的值。
我重申一下:每个测试的设置部分应该只有与最后被断言的值相关的代码。
2、操作
设置是公共部分,操作是为断言做准备的。
3、断言
使用Hamcrest库,这个库专门为断言而生。
使用纯正的JUnit
assertEquals(results.size(), 2);
assertTrue(results.contains(aHarryPotterBook))
assertTrue(results.contains(anotherHarryPotterBook))
使用Hamcrest
assertThat(results.size(), is(2));
assertThat(results, containsInAnyOrder(aHarryPotterBook, anotherHarryPotterBook));