我应该为每个功能/方法编写多少单元测试?

时间:2008-09-21 06:58:48

标签: unit-testing

您是否为每个功能/方法编写一个测试,在测试中进行多次检查,或者对每次检查进行测试?

12 个答案:

答案 0 :(得分:30)

每个检查一次测试和超级描述性名称,每个实例:

@Test
public void userCannotVoteDownWhenScoreIsLessThanOneHundred() {
 ...
}

当测试失败时,只有一个断言和使用好名称会给我一个更好的报告。他们对我尖叫:“你违反了规则!”。

答案 1 :(得分:5)

我根据功能提供的功能进行了测试。但是,每个测试可能有几个断言。 测试用例的名称表示正在测试的功能。

通常,对于一个功能,我有几个“晴天”测试和一个或几个“下雨天”场景,这取决于其复杂性。

答案 2 :(得分:4)

BDD(行为驱动开发)

虽然我还在学习,但它基本上是TDD组织/关注你的软件将如何实际使用...而不是如何开发/构建它。

Wikipedia General Info

BTW就每个测试方法是否要执行多个断言而言,我建议尝试两种方式。有时你会看到一个策略在绑定中离开你的位置,它会开始有意义为什么你通常只使用每个方法一个断言。

答案 3 :(得分:3)

我认为单一断言的规则有点过于严格。在我的单元测试中,我尝试遵循单组断言的规则 - 只要你一个接一个地进行检查,你就可以在一个测试方法中使用多个断言(你不要不要在断言之间改变测试类的状态。

所以,在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)

当然,在长期和经常使用的断言组的情况下,我喜欢创建自定义断言方法 - 这些方法对于比较复杂对象特别有用。

答案 4 :(得分:2)

每项检查的测试用例。它更精细。它使得查看特定测试用例失败变得更加容易。

答案 5 :(得分:2)

我为每个方法编写至少一个测试,并且如果该方法需要一些不同的setUp来测试好的案例和坏的情况,则会更多。

但是你应该从不在一个单元测试中测试多个方法。如果您的API发生变化,它会减少修复测试中的工作量和错误。

答案 6 :(得分:1)

我会为每张支票建议一个测试用例。 保持原子越多,结果就越好!

在单个测试中保留多个检查将帮助您生成需要纠正多少功能的报告。

保持原子测试案例将向您展示整体质量!

答案 7 :(得分:1)

通常每次检查一个测试用例。当测试围绕特定函数进行分组时,它会使重构(例如删除或拆分)更加困难,因为测试也需要进行大量更改。为类中所需的每种行为编写测试要好得多。有时,在测试特定行为时,每个测试用例进行多次检查是有意义的。然而,随着测试变得越来越复杂,当类中的某些东西发生变化时,它们就更难以改变。

答案 8 :(得分:1)

在Java / Eclipse / JUnit中,我使用两个源目录(src和test)和同一棵树。 如果我有 src / com / mycompany / whatever / TestMePlease 和值得测试的方法(例如 deleteAll(List<?> stuff)抛出MyException )我创建一个 test / com / mycompany / whatever / TestMePleaseTest 以及测试不同用例/场景的方法:

@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*/);
}

不知道是否有更明智的方法可以做到这一点,说实话......

答案 9 :(得分:1)

我喜欢在方法中对每次检查进行测试,并为测试方法提供有意义的名称。例如:

testAddUser_shouldThrowIllegalArgumentExceptionWhenUserIsNull

答案 10 :(得分:0)

每张支票都有一个测试用例。如果您恰当地命名方法,当其中一个测试导致回归失败时,它可以为问题提供有价值的提示。

答案 11 :(得分:0)

我尝试将数据库测试和业务逻辑测试分开(使用此处推荐的其他人使用BDD),首先运行数据库测试确保数据库处于良好状态,然后再要求应用程序使用它。< / p>

有一个很好的podcast show with Andy Leonard on what it involves and how to do it,如果你想了解更多信息,我写了blog post on the subject(无耻的插件; o)

相关问题