每个函数/方法应编写多少个单元测试?
我们是否为每个功能/方法编写一个测试,在测试中包含多个检查,或者为每个检查编写一个测试?
解决方案
每个检查的测试用例。更精细。这样可以更轻松地查看失败的特定测试用例。
BDD(行为驱动开发)
尽管我仍在学习,但它基本上是TDD的组织/侧重于软件的实际使用方式,而不是软件的开发/构建方式。
维基百科
基本信息
顺便说一句,至于是否针对每个测试方法执行多个断言,我建议我们尝试两种方式。有时,我们会看到一种策略将我们留在绑定中的位置,这开始使我们理解为什么通常每个方法只使用一个断言。
我会为每个检查建议一个测试用例。
我们保持原子性越强,结果就越好!
将多个检查保持在单个测试中将有助于我们生成需要更正多少功能的报告。
保留原子测试用例将为我们显示整体质量!
每个检查一个测试用例。如果适当地命名方法,当这些测试之一导致回归失败时,它可以为问题提供有价值的提示。
我对该功能提供的功能进行了测试。但是,每个测试可能有几个断言。
测试用例的名称表示正在测试的功能。
通常,对于一项功能,我会根据其复杂性进行几次"晴天"测试和一个或者几个"雨天"场景。
我为每种方法编写至少一个测试,如果该方法需要一些不同的设置来测试好的情况和坏的情况,则要花更多的时间。
但是,我们绝不能在一个单元测试中测试一种以上的方法。如果API发生更改,它可以减少修复测试的工作量和错误。
每个检查项和超级描述性名称一个测试,每个实例:
@Test public void userCannotVoteDownWhenScoreIsLessThanOneHundred() { ... }
测试失败时,只有一个断言和使用好名字都可以为我提供更好的报告。他们对我尖叫:"我们违反了该规则!"。
我尝试将数据库测试和业务逻辑测试(此处建议使用BDD)分开,首先运行数据库,以确保数据库处于良好状态,然后再要求应用程序使用它。
安迪·伦纳德(Andy Leonard)进行了一场精彩的播客节目,内容涉及其中以及如何做,如果我们想了解更多信息,我已经写了一篇有关该主题的博客文章(无耻的插件; o)
通常,每个检查一个测试用例。如果将测试按特定功能分组,则会使重构(例如删除或者拆分)的功能更加困难,因为测试也需要进行大量更改。最好为类中所需的每种行为编写测试。有时,在测试特定行为时,每个测试用例进行多次检查是有意义的。但是,随着测试变得越来越复杂,当类中的某些内容发生更改时,它们也将变得更难更改。
在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*/); }
不知道有没有更聪明的方法来告诉你真相...
我喜欢在一个方法中对每个检查进行一次测试,并为测试方法起一个有意义的名称。例如:
testAddUser_shouldThrowIllegalArgumentExceptionWhenUserIsNull
我认为单一声明的规则有点太严格了。在单元测试中,我尝试遵循一组断言的规则-我们可以在一种测试方法中使用多个断言,只要我们一个接一个地进行检查(我们不更改被测试类的状态)在断言之间)。
因此,在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)
当然,如果断言组很长且经常使用,我喜欢创建自定义断言方法-这些方法在比较复杂对象时特别有用。