你是以每个函数/方法一个测试,还是在一个测试中包含多个检查,或者是为每个检查编写一个测试?
每次检查一个测试,并使用超级描述性的名称:
@Test
public void userCannotVoteDownWhenScoreIsLessThanOneHundred() {
...
}
单个断言和良好的命名,在测试失败时给我的报告更佳。它们对我喊道:“你违反了那个规则!”。
userCannotVoteDownWhenScoreIsLessThanOneHundred
-> User_cannot_vote_down_when_Score_is_less_than_one_hundred
- Theodor我有一个测试针对函数提供的每个能力。然而,每个测试可能有几个断言。测试用例的名称指示正在测试的功能。
一般来说,对于一个函数,我有几个“晴天”测试和一个或几个“雨天”场景,这取决于它的复杂性。
我认为单一断言规则有点过于严格。在我的单元测试中,我尝试遵循单一断言组的规则 -- 你可以在一个测试方法中使用多个断言,只要你按顺序进行检查(在断言之间不改变被测试类的状态)。
因此,在Python中,我相信像这样的测试是正确的:
def testGetCountReturnsCountAndEnd(self):
count, endReached = self.handler.getCount()
self.assertEqual(count, 0)
self.assertTrue(endReached)
但这个应该被分成两个测试方法:
def testGetCountReturnsOneAfterPut(self):
self.assertEqual(self.handler.getCount(), 0)
self.handler.put('foo')
self.assertEqual(self.handler.getCount(), 1)
当然,在长期和频繁使用的断言组中,我喜欢创建自定义断言方法——这些方法对于比较复杂的对象特别有用。
每个检查都需要一个测试用例。这样更加细致。它使得很容易看到哪个具体的测试用例失败了。
testAddUser_shouldThrowIllegalArgumentExceptionWhenUserIsNull
@Test
public void deleteAllWithNullInput() { ... }
@Test(expect="MyException.class") // not sure about actual syntax here :-P
public void deleteAllWithEmptyInput() { ... }
@Test
public void deleteAllWithSingleLineInput() { ... }
@Test
public void deleteAllWithMultipleLinesInput() { ... }
对我来说,拥有不同的检查更容易处理。
然而,由于每个测试都应该是一致的,如果我想让我的初始数据集保持不变,有时我需要在同一个检查中创建和删除内容,以确保其他测试发现数据集是原始的:
@Test
public void insertAndDelete() {
assertTrue(/*stuff does not exist yet*/);
createStuff();
assertTrue(/*stuff does exist now*/);
deleteStuff();
assertTrue(/*stuff does not exist anymore*/);
}
说实话,我不知道是否有更聪明的方法来做这件事...
output YourFunction(input) { return DEFAULT_OUTPUT; }
将通过所有测试,但您不希望如此。 - mercury0114