项目编写单元测试的哪些部分几乎或几乎不可能?数据访问? FTP?
如果对这个问题有答案,则%100覆盖率是一个神话,不是吗?
答案 0 :(得分:37)
Here我发现(通过haacked Michael Feathers说的可以回答:
他说,
如果出现以下情况,则测试不是单元测试:
- 与数据库对话
- 通过网络进行通信
- 它触及文件系统
- 它不能与任何其他单元测试同时运行
- 您必须对您的环境执行特殊操作(例如编辑配置文件)才能运行它。
他在同一篇文章中再次提到:
通常,单元测试应该很小,它们测试方法或几种方法的交互。当您将数据库,套接字或文件系统访问权限提取到单元测试中时,它们不再是那些方法;它们是关于将代码与其他软件集成的。
答案 1 :(得分:13)
100%的报道是一个神话,它并不意味着80%的报道是无用的。当然,目标是100%,在单元测试和集成测试之间,你可以接近它。
单元测试中不可能的是预测所有完全奇怪的您的客户将对产品做的事情。一旦你开始发现这些令人难以置信的代码转换,请确保将测试卷回到测试套件中。
答案 2 :(得分:10)
实现100%的代码覆盖几乎总是浪费。有很多资源。
单位测试没有什么是不可能的,但总有收益递减。单元测试可能不值得单元测试。
答案 3 :(得分:7)
目标不是100%的代码覆盖率,也不是80%的代码覆盖率。单元测试易于编写并不意味着您应该编写它,并且单元测试难以编写并不意味着您应该避免这种努力。
任何测试的目标都是以最友好的方式检测用户可见的问题。
由测试标记的创作,维护和诊断问题(包括误报)的总成本是否值得特定测试捕获的问题?
如果测试捕获的问题是“昂贵的”,那么你可以付出努力去弄清楚如何测试它,并保持测试。如果测试捕获的问题是微不足道的,那么编写(并维护!)测试(即使存在代码更改)也更容易实现。
单元测试的核心目标是保护开发人员免受实现错误的影响。仅这一点就应该表明过多的努力将是一种浪费。在某一点之后,有更好的策略来获得正确的实施。此外,在某一点之后,用户可见的问题是由于正确实现了错误的事情,只能通过用户级别或集成测试来捕获。
答案 4 :(得分:4)
你不会测试什么?任何不可能破坏的东西。
在代码覆盖方面,您希望实现100%实际编写的代码 - 即您无需测试第三方库代码或操作系统代码,因为该代码已经交付给您测试。除非不是。在这种情况下,您可能想要测试它。或者如果存在已知错误,在这种情况下您可能需要测试是否存在错误,以便获得修复错误的通知。
答案 5 :(得分:3)
可以进行数据访问,因为您可以设置测试数据库。
通常,“不可测试”的东西是FTP,电子邮件等等。但是,它们通常是您可以依赖的框架类,因此不需要测试是否将它们隐藏在抽象之后。
此外,100%的代码覆盖率本身还不够。
答案 6 :(得分:3)
我猜想,GUI的单元测试也很困难,尽管并非不可能。
答案 7 :(得分:2)
任何不完全确定的东西都是单元测试的禁忌。您希望您的单元测试始终以相同的初始条件通过或失败 - 如果线程,随机数据生成,时间/日期或外部服务等奇怪现象会影响这一点,那么您不应该在单元测试中覆盖它。时间/日期是一个特别令人讨厌的案例。您通常可以构建代码以使用注入日期(通过代码和测试),而不是依赖于当前日期和时间的功能。
尽管如此,单元测试不应该是应用程序中唯一的测试级别。实现100%的单元测试覆盖通常是浪费时间,并且很快就会收到递减的回报。
更好的是拥有一套更高级别的功能测试,甚至是集成测试,以确保系统正常工作“一旦它全部加入” - 单元测试定义不要测试。
答案 8 :(得分:2)
@GarryShutler
我实际上是使用虚假的smtp服务器(Wiser)对电子邮件进行单元测试。确保您的应用程序代码正确无误:
http://maas-frensch.com/peter/2007/08/29/unittesting-e-mail-sending-using-spring/
可能会为其他服务器做类似的事情。否则你应该能够模拟API ...
BTW:100%的覆盖率只是一个开始......只是意味着所有代码实际上都是bean执行一次 ....没有关于边缘情况等等。答案 9 :(得分:2)
大多数需要巨大且昂贵的(资源或计算时间成本)设置的测试都是集成测试。单元测试应该(理论上)只测试代码的小单元。个人职能。
例如,如果您正在测试电子邮件功能,那么创建模拟邮件是有意义的。该模拟的目的是确保您的代码正确调用邮件程序。要查看您的应用程序是否实际发送邮件,请进行集成测试。
区分单元测试和集成测试非常有用。单元测试应该非常快。在您签入代码之前,应该可以轻松地运行所有单元测试。
但是,如果您的测试套件包含许多集成测试(设置和拆除数据库等),那么您的测试运行可能会超过半小时。在这种情况下,开发人员很可能在签入之前不会运行所有单元测试。
所以回答你的问题:做网络单元测试的东西,更好地作为集成测试实现(并且不测试getter / setter - 这是浪费时间;-))。
答案 10 :(得分:2)
在单元测试中,您不应测试任何不属于您单位的内容;在他们的背景下测试单位是另一回事。这是一个简单的答案。
我使用的基本规则是你应该对触及你单位边界的任何东西进行单元测试(通常是课程,或者你的单位可能是其他任何东西),然后嘲笑其余部分。无需测试某些数据库查询返回的结果,只需测试您的单元是否吐出正确的查询。
这并不意味着你不应该省略那些难以测试的东西;使用正确的工具可以很好地测试异常处理和并发问题。
答案 11 :(得分:2)
“单元测试涉及什么不测试?” *豆类只有吸气剂和二传手。推理:通常浪费时间可以更好地用于测试其他东西。
答案 12 :(得分:1)
您可以测试它们,但它们不是单元测试。单元测试是不跨越边界的,例如跨越线路,命中数据库,运行/与第三方交互,触摸未经测试/遗留的代码库等。
除此之外的任何事情都是集成测试。
标题中问题的明显答案是你不应该对你的API的内部进行单元测试,你不应该依赖别人的行为,你不应该测试任何你不负责的事情。
其余的应该足以让你能够在其中编写代码,而不是更多,而不是更少。
答案 13 :(得分:1)
FTP,SMTP,I / O一般应使用接口进行测试。接口应该由适配器(用于实际代码)和用于单元测试的模拟实现。
单元测试不应该使用真实的外部资源(FTP服务器等)
答案 14 :(得分:1)
配置是另一个很难在单元测试中测试的项目。应该针对配置完成集成测试和其他测试。这减少了测试的冗余并节省了大量时间。尝试单元测试配置通常是无聊的。
答案 15 :(得分:1)
我不同意quamrana关于不测试第三方代码的回应。这是单元测试的理想用途。如果在库的新版本中引入了错误怎么办?理想情况下,当发布新版本的第三方库时,您运行代表此库的预期行为的单元测试,以验证它是否仍按预期工作。
答案 16 :(得分:1)
在处理大型项目时,确实100%的覆盖率是一个很好的目标,但是对于大多数在部署之前修复一个或两个错误的项目,不一定值得花时间来创建详尽的单元测试。 / p>
在非常详细的级别上彻底测试表单提交,数据库访问,FTP访问等内容通常只是浪费时间;除非正在编写的软件需要非常高的可靠性(99.999%的东西),否则单元测试太多可能会造成过度杀伤和实时下沉。
答案 17 :(得分:1)
任何需要非常大而复杂的设置。当然你可以测试ftp(客户端),但是你需要设置一个ftp服务器。对于单元测试,您需要可重复的测试设置。如果您无法提供,则无法进行测试。
答案 18 :(得分:0)
首先对代码进行单元测试的主要原因是验证代码的设计。可以获得100%的代码覆盖率,但不能不使用模拟对象或某种形式的隔离或依赖注入。
请记住,单元测试不适用于用户,而是供开发人员和构建系统用于在发布之前验证系统。为此,单元测试应该运行得非常快,并且尽可能少地配置和依赖性摩擦。尽量在内存中尽可能多地做,并避免使用测试中的网络连接。
答案 19 :(得分:0)
FTP,电子邮件等可以使用服务器模拟进行测试。这很困难但可能。
不可测试的是一些错误处理。在每个代码中都存在永远不会发生的错误处理。例如,在Java中必须捕获许多异常,因为它是接口的一部分。但是使用过的实例永远不会抛出它。或者,对于所有可能的情况,如果存在一个案例块,则为交换机的默认情况。
当然可以删除一些不需要的错误处理。但是将来会出现编码错误,那么这很糟糕。
答案 20 :(得分:0)
如果设置单元测试所需状态的代码变得比要测试的代码复杂得多,我倾向于画线,并找到另一种方法来测试功能。那时你必须问你怎么知道单元测试是对的!