unit testing什么不能testing?
项目编写unit testing的哪些部分几乎或者是不可能? 数据访问? FTP?
如果有这个问题的答案,那么%100的覆盖率是一个神话,不是吗?
在这里,我发现(通过抨击迈克尔羽毛的东西可以是一个答案:
他说,
一个testing不是一个unit testing,如果:
- 它与数据库交谈
- 它通过networking进行通信
- 它涉及到文件系统
- 它不能和其他任何unit testing同时运行
- 你必须对你的环境做特别的事情(比如编辑configuration文件)来运行它。
他又在同一篇文章中补充道:
一般来说,unit testing应该是小的,他们testing一个方法或几个方法的交互。 当你将数据库,套接字或文件系统访问拉入你的unit testing时,它们不再是真正的关于这些方法的东西; 他们是关于你的代码与其他软件的整合。
100%的覆盖率是一个神话,这并不意味着80%的覆盖率是无用的。 目标当然是100%,在unit testing和集成testing之间,你可以接近它。
unit testing中不可能的是预测客户对产品所做的所有奇怪的事情。 一旦你开始发现你的代码的这些令人难以置信的变态,确保将它们的testing滚回到testing套件中。
实现100%的代码覆盖几乎总是浪费。 这里有很多资源。
没有什么是不可能的unit testing,但总是收益递减。 unit testing对unit testing来说很痛苦的事情可能不值得。
目标不是100%的代码覆盖率,也不是80%的代码覆盖率。 unit testing容易写,并不意味着你应该写,unit testing很难写,并不意味着你应该避免这种努力。
任何testing的目标都是以最可爱的方式检测用户可见的问题。
编写,维护和诊断由testing标记的问题(包括误报)的总成本是否值得特定testing捕获的问题?
如果testing所带来的问题是“昂贵的”,那么你可以付出努力去研究如何testing和维护testing。 如果testing捕捉到的问题微不足道,那么编写(并保持!)testing(即使在代码更改的情况下)也更为简单。
unit testing的核心目标是保护开发人员免于执行错误。 单就这一点就应该表明,太多的努力是浪费。 在某一点之后,有更好的策略来获得正确的实施。 用户可见的问题也是由于正确实现了错误的东西,只能通过用户级别或集成testing来实现。
你不testing什么? 任何不可能中断的事情
当涉及到代码覆盖范围时,您希望实现您实际编写的代码的100% – 也就是说,您不需要testing第三方库代码或操作系统代码,因为代码已经交付给您testing。 除非不是。 在这种情况下,你可能想要testing它。 或者在这种情况下,如果有已知的错误,您可能需要testing这些错误的存在,以便得到何时修复的通知。
GUI的unit testing也很困难,尽pipe不是不可能的。
数据访问是可能的,因为你可以设置一个testing数据库。
一般来说,“不可testing”的东西是FTP,电子邮件等等。 但是,它们通常是可以依赖的框架类,因此不需要testing是否将它们隐藏在抽象之后。
另外,100%的代码覆盖率是不够的。
@GarryShutler
我实际上通过使用假的smtp服务器(Wiser)unit testing电子邮件。 确保你的应用程序代码是正确的:
http://maas-frensch.com/peter/2007/08/29/unittesting-e-mail-sending-using-spring/
类似的东西可能可以为其他服务器完成。 否则,你应该能够嘲笑API …
顺便说一句:100%的覆盖率只是一个开始…只是意味着所有的代码实际上是一次执行的bean ….没有关于边缘案例等。
大多数testing需要巨大而昂贵的(资源或计算时间成本)设置是集成testing。 unit testing(理论上)应该只testing小部分的代码。 个别function。
例如,如果您正在testing电子邮件function,创build一个模拟邮件是有道理的。 该模拟的目的是确保您的代码正确地调用邮件程序。 看看您的应用程序是否真的发送邮件是一个集成testing。
区分unit testing和集成testing是非常有用的。 unit testing应该运行得非常快。 在检入代码之前,应该可以轻松地运行所有的unit testing。
但是,如果您的testing套件包含许多集成testing(设置和拆卸数据库等),则testing运行可能会轻松超过半个小时。 在这种情况下,开发人员很可能在进行检查之前不会运行所有的unit testing。
所以要回答你的问题:做unit testing的东西,更好地实现为集成testing(也不testinggetter / setter – 这是浪费时间;-))。
在unit testing中,你不应该testing任何不属于你的单元的东西; 在他们的背景下testing单位是另一回事。 这是简单的答案。
我使用的基本规则是,你应该unit testing任何触及你单位边界的东西(通常是课堂,或者你的单位可能是什么),然后嘲笑其余部分。 无需testing某些数据库查询返回的结果,只需testing您的单元吐出正确的查询即可。
这并不意味着你不应该忽略那些难以testing的东西; 即使exception处理和并发问题也可以使用正确的工具很好地testing。
“unit testing什么都不要testing?” 豆类只有吸气剂和二锅头。 推理:通常浪费时间可能会更好地花费在testing别的东西上。
任何不完全确定的东西都是unit testing的“否”。 你希望你的unit testing始终以相同的初始条件通过或失败 – 如果像线程,随机数据生成,时间/date或外部服务这样的奇怪现象能影响到这一点,那么你不应该在你的unit testing。 时间/date是一个特别恶劣的情况。 通常你可以devise一些代码来让date能够被注入(通过代码和testing),而不是依赖当前date和时间的function。
尽pipe如此,unit testing不应该是您的应用程序中唯一的testing级别。 实现100%的unit testing覆盖通常是浪费时间,并迅速满足收益递减。
更好的办法是进行一系列更高级别的functiontesting,甚至是集成testing,以确保系统“一旦联合起来”正确工作 – unit testing按照定义进行testing。
Pex – .NET自动化的Whiteboxtesting试图达到100%的覆盖率
任何需要非常大而复杂的设置。 当然你可以testingFTP(客户端),但是你需要设置一个FTP服务器。 对于unit testing,您需要一个可重复的testing设置。 如果你不能提供它,你不能testing它。
你可以testing它们,但是它们不会是unit testing。 unit testing是不跨越边界的,例如跨越线路,触及数据库,与第三方运行/交互,触摸未经testing/遗留的代码库等。
除此之外的任何事情都是集成testing。
标题中问题的明显答案是你不应该unit testing你的API的内部,你不应该依赖别人的行为,你不应该testing任何你不负责的东西。
其余的应该足以让你能够在里面写你的代码,而不是更多,而不是更less。
我不同意quamrana关于不testing第三方代码的回应。 这是unit testing的理想用法。 如果在图书馆的新版本中引入了错误,该怎么办? 理想情况下,当发布新版本的第三方库时,运行代表该库预期行为的unit testing,validation它是否仍然按预期工作。
另外,还有一些答案可能会从另一个问题中提取出来( 什么使得unit testing很好?
configuration是另一个在unit testing中很难testing的项目。 应该根据configuration进行集成testing和其他testing。 这减less了testing的冗余,并释放了大量的时间。 尝试unit testingconfiguration往往是轻浮的。
一般来说FTP,SMTP,I / O应该使用一个接口进行testing。 接口应该由一个适配器(用于真实代码)和一个模拟unit testing来实现。
没有unit testing应该运用真正的外部资源(FTP服务器等)
如果设置unit testing所需状态的代码比要testing的代码复杂得多,我倾向于画线,并find另一种testingfunction的方法。 在这一点上,你不得不问你怎么知道unit testing是正确的!
FTP,电子邮件等可以用服务器仿真来testing。 这是困难的,但可能的。
不可testing的是一些error handling。 在每个代码中都有error handling永远不会发生。 例如在Java中,必须捕捉许多exception,因为它是接口的一部分。 但是使用的实例永远不会抛出它。 或者,如果存在所有可能的情况下,开关的默认情况。
当然,一些不需要的error handling可以被删除。 但是,在未来有没有编码错误,那么这是不好的。
首先对代码进行unit testing的主要原因是validation代码的devise。 有可能获得100%的代码覆盖率,但不是没有使用模拟对象或某种forms的隔离或dependency injection。
请记住,unit testing不是针对用户的,而是针对开发者和构build系统在发布之前用于validation系统的。 为此,unit testing应该运行得非常快,尽可能less的configuration和依赖性摩擦。 尽量在内存中尽可能地做,并避免使用testing中的networking连接。
在一个大型项目中,确保100%的覆盖率是一个很好的目标 ,但是对于大多数在部署之前修复一个或两个错误的项目来说,创build详尽的unit testing是不值得的。
在一个非常详细的层面上对表单提交,数据库访问,FTP访问等进行彻底的testing通常只是浪费时间; 除非编写的软件需要非常高的可靠性(99.999%的东西),unit testing太多可能是过度的和实时的下沉。