没有编写单元测试的任何好的论据?

Ben*_*nee 40 unit-testing

我已经阅读了很多关于单元测试的乐趣和令人敬畏的观点.是否有一个很好的论据反对单元测试?

slu*_*ter 57

在我以前工作的地方,单元测试通常被用作与较小的测试部门一起运行的理由; 逻辑是"我们有单位测试!我们的代码不可能失败!因为我们有单元测试,我们不需要真正的测试人员!!"

当然,这种逻辑是有缺陷的.我见过很多你不相信测试的案例.我也看到很多情况,由于时间紧迫,测试变得过时 - 当你有一个星期做大工作时,大多数开发人员会花一周的时间来做真正的代码并运送产品,而不是重构单元测试第一周,然后再恳求至少另一周做真实的代码,然后花费最后一周使单元测试与他们实际编写的内容保持同步.

我还看到了单元测试中涉及的业务逻辑比隐藏在应用程序中的逻辑更具怪异性和难以理解的情况.当这些测试失败时,您需要花费两倍的时间来解决问题 - 测试存在缺陷,还是真正的代码?

现在狂热者不会喜欢这一点:我工作的地方很大程度上已经使用单元测试逃脱了,因为开发人员具有足够高的水平,很难证明编写单元测试的时间和资源是合理的(更不用说我们了使用REAL测试人员).真的.写单元测试只会给我们带来最小的价值,投资回报就不存在了.当然它会给人一种温暖的模糊感觉 - "我可以在晚上睡觉,因为我的代码是通过单元测试保护的,因此宇宙处于一个很好的平衡状态",但现实是我们在编写软件的业务,而不是给经理们温暖的模糊感受.

当然,进行单元测试绝对有充分的理由.单元测试和TDD的问题是:

  • 有太多人打赌家庭农场.
  • 太多人将其用作宗教而不仅仅是一种工具或其他方法.
  • 太多人试图从中赚钱,这已经扭曲应该如何使用它.

在现实中,它应该被用来作为一个的,你在日常工作中使用的工具或方法,它不应该成为单一的方法.

  • 相反,我已经看到所有这些相同的理由被用来作为懒惰的借口."我们有真正的测试人员,为什么我还要为我的代码编写测试?" 自动化单元测试不是QA的替代品,但它们可以使QA测试人员免于繁琐的回归测试,因此他们可以专注于发现新的错误.单元测试就像复式会计.写作可能需要更长的时间,但它会在发生错误时捕获错误,而不是在发生错误后的几天,几周或几年内捕获错误. (8认同)
  • 如果你不能客观地证明他说的话对大多数地方都是正确的,我认为这不重要,因为你也不能反驳它.根据我的经验,TDD已经为我所工作过的每一家公司制造了不健康的思维方式而且没有太大的收获.我真诚地怀疑有很多例外情况浮出水面 - 因此为什么他的回答被投票了很多次. (6认同)
  • 真正的测试人员很棒,但很多公司都没有.他们有一些随机的街道人来测试应用程序. (4认同)
  • 我没有看到客观的论点.只是抱怨人们没有正确使用单元测试. (3认同)

duf*_*ymo 27

重要的是要理解它不是免费的.测试需要努力编写 - 更重要的是,维护.

项目经理和开发团队需要意识到这一点.

  • 我同意这些团队,但看到一些真实的数据会很好.似乎没有人拥有太多东西.有关宗教的争论."狂热者"是正确的词. (14认同)
  • 我不同意.使用单元测试进行编码比没有单元测试的编码更快.即使您必须为单元测试编写代码,净效果也是更快的开发.如果您的净效果较慢,您可能需要更加努力地进行TDD(先测试). (13认同)
  • 即使这样,单元测试也只能测试已知的情况.如果您忘记以特定方式执行某项功能或错误地编写测试或用例,则相关单元测试将无用且无法找到错误.如果您担心100%的代码覆盖率,您将花费大量时间处理测试代码而不是赚钱的生产代码.单元测试是一个很酷且有用的想法......只要用其他人的钱完成. (5认同)
  • @leonm - 我没有说明它是更快还是更好.我所说的只是它不是免费的.需要努力创造并维护它们.如果他们没有跟上,他们就会失去价值.热力学第二定律成立. (4认同)
  • 我们都明白了,Mahol.您不是更深入理解的唯一所有者.我所说的只是费用不是零,否则就是误导.我也说你在量化你的深刻理解方面存在问题.无论是否进行测试,您都无法计算总拥有成本.我们都理解这个价值,但我们不能把一个美元数字放在上面. (2认同)

Con*_*cht 26

实际上我的错误都不会通过单元测试找到.我的错误主要是集成或意外用例错误,为了更早发现它们,更广泛(和理想的自动化)系统测试将是最好的选择.

我正在等待更多以证据为基础,而不是基于宗教的单位测试论证,正如dummymo所说.我并不是指某些学术环境中的某些实验; 我的意思是,对于我的开发场景和编程能力而言,成本效益将是积极的.

因此,同意OP的其他答案:因为它们花费时间和成本效益没有显示出来.

  • 在我的实际经验中,单元测试对于1)明确说明哪些用例应该成功是有用的 - 有利于文档和显示_what_功能(不是如何)2)捕获错误 - 主要是设计错误,因为你从界面和向下工作和3)回归测试.你可以肆无忌惮地躲避,知道你的测试套件会在你破坏任何东西时提醒你.根据我的经验,这三件事不仅仅是证明成本的合理性. (10认同)
  • 我不否认单元测试可以提供所有这些好处.但我认为系统测试几乎可以提供相同的好处,还可以捕获单元测试会遗漏的大量错误.加上系统测试在重构时需要较少的重写,因为如果外部行为没有改变,那么系统测试仍然有效,但必须替换重构类的单元测试. (3认同)
  • 我的单元测试不会发现**您发现的**错误。那些你还没找到的怎么办?我只进行了几个月的单元测试,但我对它们发现了多少微妙的错误感到非常惊讶。通过更高级别的测试来追踪某些内容将是一场噩梦。 (2认同)

Jos*_*hua 15

您有一个不容易适应模拟的数据访问层.


Jef*_*ege 10

简单的事实是,当你编写一些代码时,你必须确保它在你说它完成之前有效.这意味着你运用它 - 构建一些脚手架来调用函数,传递一些参数,检查以确保它返回你期望的.是否有额外的工作,保持脚手架,所以你可以再次运行测试?

是的,实际上,它可以.通常情况下,即使代码正确,测试也会失败,因为您使用的数据不再一致,等等.

但是,如果你有一个单元测试框架,那么保持测试代码的成本只会比丢弃测试代码稍微多一些.虽然是,您会发现许多测试用例都会因为您使用的数据出现问题而失败,而不是代码问题,当您学习如何构建测试以尽量减少测试时问题.

是的,通过单元测试并不能保证您的系统正常运行.但它确实提供了某些子系统正在工作的保证,这不是什么.测试用例提供了有关如何调用函数的有用示例.

它不是灵丹妙药,但它是一种有用的做法.


L̲̳*_*̲̳̳ 9

正式验证.

如果你可以正式证明代码的正确性,除非测试条件带来新的变量,否则没有理由进行单元测试,在这种情况下,你仍然只进行少量的单元测试(或证明新的变量) ).

  • 如果我有一个函数`f:X - > Y`,我会测试当它从`Z`应用到值'z`时会发生什么?不.因为我不能将`f`应用于`z`,这是定义的.编写语言实现测试不是我的工作.证据依赖于假设.和单元测试一样(但是,更多*假设).无论如何,单元测试在当前主流语言中不起作用,因为现状普遍包括使用全局可访问的可变状态,平台依赖性和违反封装.那就是说我做单元测试,只是不像动态语言那么多. (3认同)

jac*_*aer 8

单元测试将告诉您一个特定的类方法是否正确设置变量(或某些变量).无论如何,形状或形式都不表示您的应用程序将正常运行或者它将处理它需要处理的环境.

您可以考虑编写测试的任何问题,您将在您的代码中处理,并且该问题永远不会出现.那么你就有300个测试通过,但是你想要测试的真实场景.因此,创建和维护测试所需的工作不一定值得.


DVK*_*DVK 5

这是通常的成本/收益分析.

成本:您需要花时间开发和维护测试,并将资源用于实际运行它们.

好处众所周知(大多数便宜的维护/重构和更少的错误).

因此,您在项目的上下文中平衡了一个与另一个.

如果它是一个一次性的快速黑客,你知道永远不会被重复使用,单元测试可能没有意义.虽然老实说,如果我看到每次一次性快速黑客的一美元,我看到多年后或更糟,多年后不得不维护/重构,我可能会成为投资SO的风险资本家之一:)

  • @walkytalky:我**讨厌**仙女. (2认同)

Lor*_*tel 5

非确定性结果.

在简单的情况下,您可以播种随机生成器(或以某种方式模拟它们)以获得可重现的结果,但是当算法很复杂时,这变得不可能,因为代码更改将改变对随机数的需求,从而改变结果.

这在商业环境中很少遇到,但在游戏中很有可能.