任何不写unit testing的好理由?
我已经阅读了许多关于unit testing的乐趣和真棒点。 我的问题是,有没有人反对unit testing有一个很好的论点?
在我以前工作过的地方,unit testing通常是用一个较小的testing部门运行的原因,逻辑是“我们有单元testing!!我们的代码不可能失败!!因为我们有unit testing,不需要真正的testing者!!“ 。
当然这个逻辑是有缺陷的。 我看到很多情况下,你不能相信testing。 我还看到很多情况下,由于时间紧迫,testing过期 – 当你有一个星期做一个大的工作,大多数开发人员会花一周的时间做真正的代码和运输产品,而不是重构unit testing第一周,然后再申请至less一个星期来做真正的代码,然后花费最后一周,使unit testing与他们实际写的更新。
我还看到了unit testing涉及的业务逻辑比埋在应用程序中的逻辑更加怪异和难以理解的情况。 当这些testing失败时,你必须花费两倍的时间来解决这个问题 – testing是否存在缺陷,或者是真实的代码?
现在,狂热分子不会喜欢这个位置:我工作的地方很大程度上已经逃脱了使用unit testing,因为开发人员的水平足够高,很难certificate编写unit testing的时间和资源是合理的(更不用说我们了使用REALtesting人员)。 真的。 编写unit testing只会给我们最小的价值,投资回报就是不存在的。 当然这会给人一种温暖的模糊感觉 – “我可以在晚上睡觉,因为我的代码受到unit testing的保护,因此宇宙处于一个很好的平衡状态” ,但现实是我们在写软件,而不是给pipe理者温暖的模糊感受。
当然,有unit testing的绝对理由。 unit testing和TDD的麻烦是:
- 太多的人赌上家庭农场
- 太多人把它当作一种宗教,而不仅仅是一种工具或另一种方法
- 有太多的人试图从中赚钱,这使得应该如何使用它
实际上,它应该被用作日常使用的工具或方法之一,它永远不应该成为单一的方法论。
知道这不是免费的是很重要的。 testing需要努力写作 – 更重要的是维护。
项目经理和开发团队需要了解这一点。
几乎没有我的错误将被发现unit testing。 我的错误主要是集成或意外使用情况的错误,为了更早地发现它们,更广泛的(和理想的自动化的)系统testing将是最好的select。
dummymo说,我正在等待更多的以证据为基础,unit testing的宗教信仰较less的论点。 在某些学术环境中,我不是指一些实验; 我的意思是说,对于我的发展scheme和编程能力来说,成本效益是积极的。
所以,要同意OP的其他答案:因为它们花费的时间和成本效益没有显示出来。
你有一个数据访问层不容易适应嘲笑。
简单的事实是,当你编写一些代码时,你必须确保它在你完成之前能够正常工作。 这意味着你要练习它 – build立一些脚手架来调用函数,传递一些参数,检查以确保它返回你所期望的。 是不是太多的额外的工作,保持脚手架,所以你可以再次运行testing?
是的,实际上,它可以。 即使代码是正确的,testing也会失败,因为您使用的数据不再一致,等等。
但是,如果你有一个unit testing框架,保持testing代码的成本只能比抛出更多的工作。 而当然,你会发现很多testing用例会因为你使用的数据的问题而失败,而不是代码的问题,当你学习如何构造你的testing以便最小化问题。
诚然,通过你的unit testing并不能保证你的系统工作。 但它确实提供了某些子系统正在工作的保证,这不是什么。 testing案例提供了有用的例子,说明函数是如何被调用的。
这不是万能的,但这是一个有用的做法。
正式validation。
如果你能正式certificate代码的正确性,除非testing条件引入新的variables,否则没有理由对它进行unit testing,在这种情况下,你仍然只有less量的unit testing(或者certificate新的variables)。
unit testing会告诉你一个特定的类方法是否正确地设置了一个variables(或者是一些变化)。 这不以任何forms或forms表明您的应用程序将正常运行,或者将处理它将需要处理的情况。
任何你可以考虑编写testing的问题,你将会在你的代码中处理,而这个问题永远不会出现。 那么,你有300个testing通过,但你真的不想testing的真实世界的场景。 然后,创build和维护testing所需的努力并不一定是值得的。
这是通常的成本/收益分析。
成本:您需要花时间开发和维护testing,并将资源投入实际运行。
好处是众所周知的(大多数更便宜的维护/重构与更less的错误)。
所以,在项目的背景下,你们相互平衡。
如果这是一个一次性的快速入侵,你知道永远不会被重用,unit testing可能没有意义。 虽然老实说,如果我每天都有一美元的快速破解,而且几年之后还是更糟的,那么在几年之后不得不进行维护/重构,我可能会成为风险投资人之一,投资于此:)
- testing就像保险一样。
- 你不把所有的钱都放在里面。
- 但是你不能避免你的人寿保险。 (美国人应该还记得健康保险法案)。
- 保险是必不可less的。
- 但是但是…
- 你没有得到保险,期待一个致命的事故,以恢复你投入到你的保险计划的所有钱。
综上所述,
- 有一些理由写testing。
- unit testing有时是前进的许多方法之一
- 但是 ,完全专注于写作(单元)testing是没有道理的。
非确定性结果。
在简单情况下,您可以播种随机发生器(或以某种方式模拟它们)以获得可重现的结果,但是当algorithm复杂时,这将变得不可能,因为代码更改将改变对随机数的需求,从而改变结果。
这在商业环境中很less遇到,但是在游戏中很可能会遇到。
懒惰,有时我很懒,只是不想做!
但是严格的unit testing是非常棒的,但是如果我只是为自己的享受编码,我一般不会这样做,因为项目是短暂的,我只有一个人在工作,而且他们不是那么大。
-
这可能会阻碍尝试多种变化,特别是在项目的早期阶段。 (但也可以鼓励在后期尝试!)
-
它不能代替系统testing,因为它没有涵盖组件之间的关系。 因此,如果您必须将系统testing和unit testing之间的可用testing时间分开,那么过多的unit testing会对系统testing的数量产生负面影响。
我想补充一点,我通常鼓励unit testing!
在unit testing将提供成本效益的地方,而不是在哪里,概括是不可能的。 我看到很多人强烈地支持unit testing,并指责那些不使用TDD的人,而完全忽略了应用程序可能与真实世界不一样的事实。
例如,当你在系统之间,或者在你自己的应用程序的进程和线程之间有很多的集成点的时候,unit testing是非常困难的。
如果你所做的一切都是像Stackoverflow这样的网站,那里的问题领域是很好理解的,而且大多数解决scheme都是相当简单的,那么是的,编写unit testing有很多好处,但是有很多应用程序根本不可能单位正确testing,因为他们缺乏,以及“单位”。
我不会说这是一个反对它的论点,但是对于我们来说,我们有一个具有TON代码的遗留应用程序,并使用COBOL编写。 在这一点上,几乎不可能说我们想要实施unit testing,并且在duffymo指出的任何准确度或合理的时间范围内进行业务。
所以我想补充一点,也许有一个论点是,在开发完成(并且维护多年)之后,无法(在某些情况下)尝试执行unit testing。
我同意这样的观点,即一般来说,对于unit testing是没有好的理由的。 然而,在某些特定情况下,unit testing可能不是一个可行的select,或者至less是有问题的,并且/或者对于创build和维护testing所涉及的努力水平提出了难以回报的投资build议。
这里有些例子:
-
响应外部条件的实时依赖行为。 一些纯粹主义者可能会争辩说,这不是unit testing,而是涉及集成或系统testing级别的场景。 不过,我已经为准embedded式应用程序编写了简单的低级function代码,通过unit testing框架至less部分地testing实时响应,以便进行构build/回归testing。
-
testing需要testing代码模块响应的环境状态的复杂数据描述的行为和/或策略级function。 这与早期的海报评论有关unit testing涉及难以适应嘲笑的数据访问层的困难。 虽然被testing的行为/策略可能相对简单,但需要在复杂的状态描述中进行testing。 这里进行unit testing的价值在于确保为关键任务应用程序正确处理罕见而关键的条件。 人们想嘲笑后者,创造一个模拟的环境/状态,但这样做的代价可能很高。
对于上述情况,unit testing至less有两种select:
-
对于实时或准实时functiontesting,可以进行广泛的系统testing,以弥补缺乏良好的unit testing。 对于一些应用来说,这可能是唯一的select,例如涉及硬件和/或物理系统的embedded式系统。
-
创build一个testing工具或系统级模拟器,以便在一系列随机模拟条件下进行广泛的testing。 这对于testing前面描述的涉及复杂环境状态的策略/行为场景可能是有用的。 尽pipe在创buildtesting工具或模拟器时可能涉及到大量的工作,但是由于可以testing更为广泛的条件范围,所以投资回报率可能比单独的unit testing要好得多。
由于testing环境涉及随机而非特定的条件,因此这种方法可能无法提供某些任务关键场景所需的相当程度的保证。 进行广泛的testing可能有助于弥补这一点。 或者,为随机条件创buildtesting设备或系统模拟器也可能有助于降低testing特定复杂状态场景的总成本,因为开发成本现在在更广泛的testing需求中共享。
最后,如何最好的方法来testing任何给定的应用程序归结为成本与价值。 unit testing是最好的select之一,应该总是在可行的地方使用,但并不是普遍适用于所有情况。 像软件中的许多事情一样,有时这只是一个必须做的判断,然后准备根据结果做出调整。
我们不是完全摆脱它们,而是仅为支付授权,用户authentication等核心function编写unit testing。这是非常有用的,因为总是会有一些接触点对大代码中的代码更改非常敏感基地,你会想要某种方式来validation这些接触点的工作没有失败的质量保证。
永远不要写unit testing。
有很好的理由不写特定的unit testing。 (特别是如果你使用代码生成,当然你可以编写代码生成unit testing,以确保没有人用代码生成代码,但这取决于相信团队)。
*编辑
哦。 从我所了解的函数式编程中的一些东西,编译工作或不编译。
那些东西需要unit testing吗?
一般来说写unit testing,学习曲线是我知道不要打扰的最大原因。 我现在一直在尝试学习好的unit testing,现在我觉得我只是在做好它(编写审计日志间谍,嘲笑,testing每个testing1个约束等),虽然我觉得它已经加快了当时约一年的发展。 所以说,在它真正开始回报之前,要经过6个月的努力。 (当然,那段时间我还在做“真正的”工作)。
那段时间所经历的大部分痛苦是由于未能遵循良好的unit testing准则而导致的。
对于各种具体情况,unit testing的能力可能被阻挡; 其他人则对其中的一些人进行了评论。
unit testing是一个权衡。 我看到两个问题:
-
这需要时间。 不仅要写testing,还要(如果你想做一个重要的改变,这是最烦人的),现在你有两个地方需要修改。 在最坏的情况下,它可能会阻止你重新构build你的代码库。
-
它只能防止你认为会出现的问题,而且你大多不能testing副作用。 这可能会导致如前所述的虚假的安全感。
我同意unit testing是提高具有相对稳定的代码库的企业软件的可靠性的有价值的工具。 但对于个人项目或婴儿项目,我认为在代码中大量使用断言是一个更好的折衷。
在testing驱动开发中,unit testing实际上更重要的是devise你的代码的可testing性。 事实certificate,你的代码往往更模块化,编写testing有助于充实API等等。
然而,通常情况下,您会发现自己正在开发代码,然后编写testing,注释掉刚写入的代码,以确保testing失败,然后有select地删除注释令牌以使testing通过。 为什么? 那么因为编写testing比在某些情况下编写代码要困难得多。 编写可以以完全自动化的方式进行testing的代码通常要困难得多。 考虑用户界面,生成图像或pdf的代码,数据库事务。
所以unit testing确实有很大帮助,但是希望为testing编写大约3倍的代码,而不是为实际代码编写代码。 而且所有这些都需要维护。 应用程序的重大变化将使大量的testing无效 – 这是对系统影响的一个很好的衡量标准,但是…你准备好了吗? 你在一个小团队,你在做5个开发人员的工作吗? 如果是这样的话,那么自动化的TDD开发就不会飞了 – 你将不会有足够的时间来完成足够的东西。 那么你最终会依赖于你自己的手动testing,QAtesting的东西以及只是生活中的漏洞,然后修复东西。 这是不幸的,高压和恼人的,但小公司却没有聘请足够的开发人员来完成需要完成的工作。
不,我真的没有。 根据我的经验,有人提出一个稻草人的论点,或者只是不知道如何unit testing不明显的unit testing。
@Khorkak – 如果你改变了你的产品代码中的一个特性,那么你的unit testing只会被影响。 如果你不这样做,那就意味着你不是孤立地解耦你的生产代码和testing,而是在生产代码中集成大块的生产代码。 这只是unit testing技能差,是的,这是一个大问题。 不仅因为你的unit testing代码库将变得难以维护,而且还因为你的生产代码库会吮吸并且有同样的问题。
unit testing对一次性代码没有任何意义:如果代码是概念的Q&Dcertificate,在尖峰期间创build的东西来研究各种方法,或者其他任何你确定的东西几乎总是会被抛弃,然后做unit testing不会带来很多投资回报。 事实上,他们可能会伤害你,因为花在那里的时间是不花时间去尝试不同的方法等(替代成本)
关键是肯定是这样的,或者与队友等有足够的了解,如果有人说'那太棒了,那就用那个',然后你花时间把代码提高到NON一次性代码的标准。
对于那些要求更好的certificate,我会把你引向这个页面。 研究注意到,这些研究中有很多是学术types的研究,但是针对做真正的生产软件工作的团队进行研究,所以个人来说,它们似乎具有相当多的有效性。