我工作的第一家真正的软件公司就是单元测试(NUnit).我当时并不知道我们是真正的坚持者 - 我不知道我们的代码覆盖是什么样的,我正在编写大部分的单元测试.从那时起,我遇到了一些进行大量测试的公司,但它是主席测试:依赖于那里的人,重复性低,捕获bug的可能性低.另一种态度是:这是他们想要"未来"的事情; 基本上当钱从天而降.
我想念单元测试 - 它让生活更轻松.但我发现,当我寻找新工作时,单元测试要么是公司希望在未来"开始",要么是根本不做的事情(呃,它已经存在了一段时间)现在!).我要说的是,过去两年我所看到的60-75%的工作要求都没有列出单元测试.我只能想到一个或两个具有单元测试经验的要求(对于中级开发人员的职位).
所以问题是,缺少什么?我认为这会让人们更有成效,但这只是在花了大量时间实际做到这一点之后.关于单元测试的成本节省是否有任何好的研究?这是我正在关注的公司类型吗?
编辑:即使标题是一个有点恶魔的倡导者,我认为自己是一个单位测试支持者.
根据我的经验,这涉及到几个因素:
管理层并不真正了解单元测试究竟是什么,或者为什么它对它们具有真正的内在价值.
管理层倾向于更关注快速的产品交付,并且(错误地)认为单元测试对该目标起反作用.
人们误以为测试完全属于质量保证的范围.开发人员是编码人员,无法编写测试.
尽管这些工具是免费提供的,但管理层必须花钱进行正确的单元测试,这是一种常见的误解.(当然,开发人员需要考虑时间,但这并不是真的让人望而却步.)
威尔的答案将围绕这个答案:确定测试代码的价值非常困难(编辑jcollum)
当然,还有其他因素,但这些正是我到目前为止所遇到的.
1)很难
2)需要时间
3)确定测试代码的价值非常困难
第3点是粘性的.良好的单元测试可以减少错误.但良好的生产代码也是如此.您如何确定由于您的单元测试而不存在多少错误?你不能衡量不存在的东西.您可以指向研究,但它们并不适合您的业务经理的电子表格.
这是很容易把所有的责任推到"管理",但被管理真的告诉你具体没有做任何的单元测试?
管理一般不会(也可能不会)告诉您如何完成工作,无论是模块化,抽象数据类型,设计模式还是单元测试.这些是成功,有能力的软件工程师适用的交易工具,但是一个糟糕的工程师却不适用.
我认为你问题的真正答案是:单元测试真的很难,计算机科学的学生也没有接受过这方面的培训.
在编写自己的字符串类时很容易.当您测试真实产品时,您会遇到没有人在powerpoint幻灯片中告诉您的挑战:
用户互动.应用程序的一半是用户界面逻辑.你如何以自动方式测试它,如果你移动一个按钮,它不会崩溃?
与外部API和框架的交互.如果您正在编写Windows内核驱动程序,那么如何对其进行单元测试?您是否为您使用的每个IRP和内核函数编写存根,有效地创建了OS内核的模拟?
网络通信是21世纪的事情.如何协调由多个分布式组件组成的单元测试?
你如何选择好的测试用例?我经常看到人们尝试"在1000次迭代的循环中做随机事情,看看它是否破坏"的方法.当你这样做时,努力高于回报,错过重要的错误,并放弃单元测试.
您如何测试满足性能要求?
对测试模式的了解很少:存根,预设响应,回归测试是大多数人不知道的概念.你工作场所有多少人真正读过一本关于单元测试的书?
我们可以归咎于管理的一件事是需求规范很少包含对可交付成果质量水平的任何要求.
下次你的老板要求你做一个时间估计,包括写单元测试的时间,看看会发生什么.
大多数测试不测试任何东西.
如果文件不存在,则编写fileopen()函数和单元测试失败,如果文件存在则成功.大!现在你检查它是否适用于BIG5中文文件名吗?在NFS共享?在vista上,USB密钥上的文件和UAC打开?
问题是单元测试是由编写函数的同一个程序员编写的,使用相同的假设并具有相同的技能水平.要真正发挥作用,测试必须由其他人编写,只有发布的规范才能看到代码. - 在大多数公司,只是获得书面规格将是一个突破!
单元测试检查各个功能的代码中的错误.它们可以用于数据访问层,数学库等,其中输入/输出是众所周知的,内部结构很复杂,但在很多情况下,它们只是浪费时间.
当错误是由于代码的不同部分之间或与OS和用户之间的交互引起时,它们会失败.高/低DPI设置等问题会弄乱对话框或外语设置交换'.' 通常不会找到','.
已经对单元测试的ROI进行了研究 - 请参阅此问题.
我发现很多开发人员对单元测试不感兴趣.当你开始时,它似乎总是很多工作,收益甚微.没有人想报名参加额外的工作,所以他们抗拒.一旦人们开始,他们通常会热情地坚持下去,但让他们开始可能很难.
除了采用单元测试的问题之外,单元测试并不总是值得的,尽管一般来说我认为它是正确应用的.单元测试没有什么特别之处可以使它们免于容易受到不良结构的影响.
单元测试具有成本(创建,维护和运行),只有当它们提供比这些成本更大的好处时才值得.测试创建与其他技能一样,需要特定的经验和知识才能获得成功.如果没有足够的经验,即使是经验丰富的开发人员也很容易创建低质量,低价值和/或高成本的单元测试,这些测试是不值得的.特别是考虑到单位测试的价值是多么困难.
此外,单元测试只是提高代码质量的一种方法,但这不是唯一的方法.在某些情况下,某些团队可能不是提高软件质量的最有效方法.
请记住,在单元测试中投入大量精力并不能保证高质量的软件.而且,无需任何单元测试即可生产出最高质量的软件.
有很多公司在最佳实践方面没有做任何事情.没有代码审查,没有单元测试,没有测试计划,没有任何东西,只是在裤子的座位上.
以此为契机,让他们使用持续集成平台并开发单元测试!轻松打动强大的功能,同时提高代码的质量和稳定性
编辑:至于理由,我认为他们只是不清楚当前的工具,使CI和单元测试非常容易.
好吧,我的公司没有使用TDD或单元测试.说实话,我们不知道该怎么做.我们显然可以用于像CapitalizeString()这样的愚蠢函数,但我们不知道如何为具有复杂对象的高度复杂系统做到这一点.此外,大多数受访者都没有经验或经验有限.似乎单元测试在SO人群中很大,但在可用的工作池中并不是特别大.
TDD是一个单独的主题.我们在道德上反对TDD.我们不是牛仔编码员,但我们相信它会阻碍项目的创造力和灵活性.而且,编写单元测试功能的编码器没有任何意义.当我做某事时,我会对我能想到的所有边缘情况进行编码.我需要的是另一个大脑来寻找我可能错过的东西.我们没有那个.这些团队规模小而且独立.
总之,我们不相信TDD,但我们想要单元测试.我们没有这方面的经验,我们也很难找到它.
单元测试应该只是代码开发工作流程的一个自然部分,就像编译器一样.
但是,这需要教育管理层了解单元测试的好处.不过,初级开发者获得这种影响的机会相对较低.因此,公司是否是单元测试的支持者取决于他们是否拥有高级开发人员或建筑师,他们是单元测试的倡导者.
我相信这是你的问题的答案"缺少什么,为什么没有更多的公司进行单元测试".:-)
我不认为懒惰是不良单元测试的根本原因.对于我的公司来说,时间限制和"刚刚完成"的态度是进行单元测试的最大障碍.此外,我们的系统失败的地方往往更多地处于集成级别(服务,数据库访问,需要特定数据进行测试的复杂查询),而不是"单元级别".这些东西更难测试,如果你没有足够的时间来完成这项功能,你可能没有时间同时完成任何有用的测试.
它可能是你提到过的几件事的组合.很难衡量TDD的成本节约.如果您想要外包您的IT,您可以显示您每年为员工支付的费用与签订合同的费用; 它非常具体.How do you say,"哦,这个测试抓住了一个错误,这将花了我4个小时来调试和修复......"?
有些地方不使用它的原因仅仅是因为它需要大量的工作才能开始和继续.编写单元测试所花费的时间与编写实际功能所花费的时间相似,这对于某些管理人员而言,就像您将开发人员的工作效率降低了一半.
最重要的是,您构建团队(或某人)需要将基础架构放置到位并进行维护.
正如艾伦所说,许多地方根本不使用最佳实践 - 他们只是想看到有形的东西.
我认为程序员必须开始这样做.作为开发的一部分,一些简单的测试开始很容易证明.
像单元测试这样的东西几乎总是需要快速调试转向.只需解释一下启动测试的速度要比安排正确的输入,设置调试器断点,启动应用程序等快多少.
在代码中记录测试.只需发表评论,解释测试的位置以及如何运行测试.未来的程序员会看到它,希望测试能够传播开来!