测试驱动开发的缺点?
采用测试驱动设计会给我带来什么损失?
仅列出底片;不要列出以否定形式写的福利。
解决方案
回答
我们会浪费大量时间来编写测试。当然,这可以在项目结束时通过更快地捕获错误来保存。
回答
TDD需要代码的特定组织。这可能效率低下或者难以阅读。甚至在结构上是错误的;例如,由于不能在类外部调用"私有"方法,因此必须使方法成为非私有方法以使其可测试,这是错误的。
当代码更改时,我们也必须更改测试。通过重构,这可能是一个
很多额外的工作。
回答
好了,这需要我们调试测试。同样,编写测试会花费一定的时间,尽管大多数人都认为这是一项前期投资,可以在节省时间的调试和稳定性方面在应用程序的生命周期内获得回报。
但是,我个人遇到的最大问题是要提高学科纪律,以实际编写测试。在团队中,尤其是已建立的团队中,很难说服他们花费的时间是值得的。
回答
我第二次回答有关初始开发时间的问题。我们还失去了在没有测试安全性的情况下舒适地工作的能力。我也被描述为TDD坚果吧,所以我们可能会失去几个朋友;)
回答
人们认为它慢一些。从长远来看,这不是很悲痛,它可以使我们免于沉迷,但是最终我们将编写更多的代码,因此可以说我们将时间花在"测试非编码"上。这是一个有缺陷的论点,但我们确实提出了要求!
回答
当我们达到大量测试的地步时,更改系统可能需要重新编写部分或者全部测试,具体取决于那些更改使测试无效。这可能会将相对较快的修改变成非常耗时的修改。
同样,我们可能开始更多地基于TDD而不是实际上是好的设计原则来做出设计决策。尽管我们可能有一个非常简单,简单的解决方案,无法测试TDD的要求,但是我们现在拥有了一个更为复杂的系统,实际上更容易出错。
回答
为诸如XML提要和数据库之类的"随机"数据编写测试可能很困难并且很耗时(不是那么困难)。我最近花了一些时间来处理天气数据供稿。至少因为我没有太多的TDD经验,这使编写测试相当混乱。
回答
我认为对我来说最大的问题是"投入"大量的时间。我仍然非常热爱TDD(如果我们有兴趣的话,请参阅我的博客以获取更新我的测试历程)的开始,而我实际上已经花了数小时来入门。
使大脑进入"测试模式"需要很长时间,而编写"可测试的代码"本身就是一项技能。
TBH,我谨不同意Jason Cohen关于公开私有方法的评论,这不是事实。在我的新工作方式中,我没有比以前更多的公开方法了。但是,它确实涉及架构更改,并允许我们"热插拔"代码模块,以使其他所有内容更易于测试。我们不应该使代码的内部更易于访问。否则,我们将回到一切公开的状态,其中的封装在哪里?
因此,(IMO)简而言之:
- 思考所花费的时间(即实际上是在测试)。
- 知道如何编写可测试代码所需的新知识。
- 了解使代码可测试所需的体系结构更改。
- 在尝试提高我们出色的编程技巧所需的所有其他技能的同时,提高" TDD编码器"技能:)
- 组织代码库以包括测试代码,而不会花费生产代码。
PS:如果我们想链接到肯定的链接,我已经询问并回答了几个问题,请查看我的个人资料。
回答
我们将失去进行增量更改(代码重构)的能力,并且仍然对代码执行预期的工作感到热情和模糊。我们几乎没有自由和轻松的动力来以最小的显式依赖性构造代码。 IOW,我们将可以嵌入很多依赖关系而无需注意。如果我们使用TDD,则在编写测试时依赖项将显示为痛苦/气味。
回答
我们将失去承担多个职责的大班课程。
我们也可能会失去承担多个职责的大型方法。
我们可能会失去一些重构的能力,但是我们也会失去一些重构的需求。
杰森·科恩(Jason Cohen)说了些类似的话:
TDD需要代码的特定组织。这可能在结构上是错误的。例如,由于不能在类外部调用私有方法,因此必须使方法成为非私有方法以使其可测试。
我说这表示缺少抽象-如果确实需要测试私有代码,则可能应该在单独的类中。
戴夫·曼
回答
TDD要求我们在编写代码通过这些测试之前,计划一下类将如何运行。这是一个加号和一个减号。
我发现在编写任何代码之前很难在"真空"中编写测试。根据我的经验,每当我不可避免地在编写类时却想到一些在编写初始测试时忘记了的东西时,我都会跳过测试。然后是时候不仅重构我的类,还重构我的测试了。重复三到四次,可能会令人沮丧。
我更喜欢先编写课程草稿,然后编写(并维护)一系列单元测试。草稿后,TDD对我来说很好。例如,如果报告了一个错误,我将编写一个测试以利用该错误,然后修复代码,以便测试通过。
回答
当我们不确定要采用哪种解决方案时,使用TDD进行原型设计可能会非常困难,因此预先编写测试可能很困难(除了非常广泛的测试之外)。可能会很痛苦。
老实说,我认为对于大多数项目而言,"核心开发"并没有任何实质性的弊端。通常,人们认为自己的代码足够好,不需要测试(从来没有),而那些纯朴的人也不会为编写它们而烦恼,这比应有的讨论要多得多。
回答
我们必须以不同的方式编写应用程序:一种使它们可测试的方法。首先,我们会感到惊讶,这是多么困难。
有些人发现了在写得太难之前先考虑要写什么的概念。嘲笑之类的概念对于某些人而言也可能很困难。如果不是为测试而设计的,则旧版应用程序中的TDD可能会非常困难。围绕非TDD友好的框架进行TDD也可能会很困难。
TDD是一项技能,因此初级开发人员起初可能会遇到困难(主要是因为尚未教会他们这种工作方式)。
总体而言,尽管随着人们的熟练程度而解决了弊端,我们最终还是抽象出了"臭味"代码并拥有了一个更稳定的系统。
回答
如果测试不是很彻底,我们可能会因为测试通过而陷入一种"一切正常"的错误观念。从理论上讲,如果测试通过了,则代码可以正常工作。但是,如果我们能够在第一时间完美编写代码,就不需要测试。这里的道义是要确保在调用完整的东西之前自己做一个健全性检查,而不仅仅是依靠测试。
关于这一点,如果健全性检查发现未测试的内容,请确保返回并为其编写测试。
回答
重新关注困难的,不可预见的需求是程序员的祸根。测试驱动的开发迫使我们将精力集中在已知的普通需求上,并将开发限制在已经想到的范围内。
考虑一下,我们很可能最终会针对特定的测试用例进行设计,因此我们将不会有创造力,而是开始思考"如果用户可以执行X,Y和Z,那将很酷"。因此,当用户开始对潜在的散热要求X,Y和Z感到兴奋时,设计可能过于严格地专注于已经指定的测试用例,并且将很难进行调整。
当然,这是一把双刃剑。如果我们花费所有时间为用户可能想要的每种可能的,可想象的X,Y和Z进行设计,那么我们将不可避免地永远不会完成任何事情。如果我们完成某项工作,那么任何人(包括我们自己)都将不可能知道我们在代码/设计中正在做什么。
回答
如果要进行"真实的" TDD(请阅读:首先使用红色,绿色和重构步骤进行测试),则在要测试集成点时,还必须开始使用模拟/存根。
当我们开始使用模拟时,过一会儿,我们将要开始使用依赖注入(DI)和控制反转(IoC)容器。为此,我们需要对所有内容使用接口(本身有很多陷阱)。
最终,我们必须编写更多的代码,而不是仅仅按照"普通的旧方法"编写代码。我们不仅需要编写一个客户类,还需要编写一个接口,一个模拟类,一些IoC配置和一些测试。
请记住,测试代码也应该维护和保养。测试应该与其他所有内容一样可读,并且需要花费时间来编写好的代码。
许多开发人员不太了解如何以"正确的方式"完成所有这些操作。但是因为每个人都告诉他们TDD是开发软件的唯一真实方法,所以他们会尽力而为。
这比人们想象的要难得多。通常,使用TDD完成的项目最终会产生很多人真正不了解的代码。单元测试通常会测试错误的东西,错误的方式。没有人同意好的测试应该是什么样子,甚至没有所谓的专家。
所有这些测试使"更改"(与重构相反)系统的行为变得更加困难,简单的更改变得非常困难且耗时。
如果我们阅读TDD文献,总是会有一些非常好的示例,但是在现实生活中的应用程序中,通常必须有一个用户界面和一个数据库。这是TDD变得非常困难的地方,而且大多数资料来源都没有提供好的答案。如果确实如此,它总是涉及更多的抽象:模拟对象,接口编程,MVC / MVP模式等,这又需要大量的知识,并且...我们必须编写更多的代码。
所以要小心...如果我们没有一支热情的团队,但至少没有一位经验丰富的开发人员,他们知道如何编写良好的测试,并且还了解一些有关良好体系结构的知识,那么在走TDD之路之前,我们确实必须三思而行。 。
回答
TDD的缺点是,它通常与"敏捷"方法紧密相关,该方法不重视系统文档,而是理解测试"应该"返回一个特定值而不是其他任何值仅存在于开发人员的背后的原因。头。
一旦开发人员离开或者忘记了测试返回一个特定值而不返回其他特定值的原因,我们就被搞砸了。如果TDD充分记录在案,并且周围环绕着人类可读的文件(即,尖尖的经理),则可以在5年内(当世界变化且应用也需要使用它时)进行引用。
当我谈论文档时,这不是代码的模糊,而是应用程序外部存在的官方书面材料,例如用例和背景信息,经理,律师和需要更新的可怜树液可以参考这些信息代码在2011年。
回答
我遇到过几种情况,TDD使我发疯。列举一些:
- 测试用例的可维护性:如果我们在大型企业中,那么很多机会是我们不必自己编写测试用例,或者至少当我们进入公司时,大部分都是由其他人编写的。应用程序的功能会不时更改,如果我们没有合适的系统(例如HP Quality Center)来跟踪它们,我们将很快发疯。这也意味着新团队成员将花费大量时间来掌握测试用例的进展。反过来,这可以转化为更多的资金需求。
- 测试自动化的复杂性:如果将部分或者全部测试用例自动化到机器可运行的测试脚本中,则必须确保这些测试脚本与其相应的手动测试用例保持同步,并且与应用程序的更改保持一致。另外,我们将花费时间调试有助于捕获错误的代码。我认为,这些错误中的大多数来自测试团队未能在自动化测试脚本中反映应用程序更改。业务逻辑,GUI和其他内部内容的更改可能会使脚本停止运行或者运行不可靠。有时,这些变化非常微妙,难以检测。一旦我的所有脚本都报告失败,因为它们的计算基于表1的信息,而表1现在是表2(因为有人在应用程序代码中交换了表对象的名称)。
回答
让我补充一下,如果将BDD原理应用于TDD项目,则可以缓解此处列出的一些主要缺点(混乱,误解等)。如果我们不熟悉BDD,则应阅读Dan North的介绍。他提出这个概念是为了回答由于在工作场所中使用TDD而引起的一些问题。 Dan的BDD简介可以在这里找到。
我之所以提出这一建议,是因为BDD解决了其中的一些负面问题,并起到了一定的作用。我们需要在收集反馈时考虑这一点。
回答
在第一个TDD项目中,有两个重大损失,时间和人身自由
我们浪费时间是因为:
- 创建一个全面的,可重构的,可维护的单元测试和验收测试套件可以为项目的第一次迭代增加大量时间。从长远来看,这可能可以节省时间,但同样地,我们也可以节省时间。
- 我们需要选择一套核心工具并成为专家。单元测试工具需要某种模拟框架的补充,并且两者都必须成为自动化构建系统的一部分。我们还希望选择并生成适当的指标。
我们失去个人自由是因为:
- TDD是一种非常有纪律的代码编写方式,往往会与技能等级最高和最低的人产生摩擦。始终以某种方式编写生产代码并使工作受到不断的同行审查可能会吓到我们最差和最好的开发人员,甚至导致人员减少。
- 嵌入TDD的大多数敏捷方法都要求我们不断与客户讨论我们打算完成的工作(在本故事中/每天/无论如何)以及权衡取舍。再一次,这不是每个人都可以喝的,无论是在围栏的开发者方面还是在客户方面。
希望这可以帮助
回答
最大的缺点是,如果我们确实想正确执行TDD,则必须先失败很多,然后才能成功。鉴于有多少软件公司在工作(按KLOC美元计),我们最终将被解雇。即使代码更快,更干净,更易于维护且漏洞更少。
如果我们在一家由KLOC支付报酬的公司(或者已实施的要求-即使未经测试),则远离TDD(或者代码审查,结对编程,或者持续集成等)。
回答
在项目中花一些时间才能开始使用它,但是...当我发现自动测试可以很快发现的愚蠢错误时,我总是后悔没有采用测试驱动方法。另外,TDD改善了代码质量。
回答
- 单元测试需要编写更多的代码,因此开发的前期成本更高
- 需要维护更多代码
- 需要额外的学习
回答
有几个缺点(我并不是在声称没有任何好处,尤其是在编写项目基础时,最终可以节省很多时间):
- 大量的时间投入。对于简单的情况,我们将损失实际实现的20%,但是对于复杂的情况,我们将损失更多。
- 额外的复杂性。对于复杂的案例,测试案例很难计算,我建议在这种情况下尝试使用将在调试版本/测试运行中并行运行的自动参考代码,而不是最简单案例的单元测试。
- 设计影响。有时,设计一开始就不清楚,并且会随着发展而不断发展-这将迫使我们重做测试,这会浪费大量时间。我建议在这种情况下推迟单元测试,直到我们对设计有所了解。
- 连续调整。对于数据结构和黑匣子算法,单元测试将是完美的,但是对于倾向于更改,微调或者微调的算法,这可能会导致大量的时间投入,而人们可能认为这是不合理的。因此,当我们认为它确实适合系统并且不要强迫设计适合TDD时,请使用它。
回答
我们必须确保测试始终是最新的,开始忽略红灯的那一刻就是测试变得毫无意义的那一刻。
我们还必须确保测试是全面的,否则当出现大错误时,我们最终说服让我们花时间编写更多代码的闷闷的管理类型就会抱怨。
回答
最大的问题是不知道如何编写适当的单元测试的人。他们编写了彼此依赖的测试(并且与Ant一起运行时效果很好,但是当我从Eclipse运行它们时,突然突然失败了,只是因为它们以不同的顺序运行)。他们编写的测试不测试任何东西,特别是他们只是调试代码,检查结果并将其更改为测试,称为" test1"。它们扩大了类和方法的范围,只是因为为它们编写单元测试会更容易。单元测试的代码非常糟糕,存在所有经典的编程问题(重耦合,500行长的方法,硬编码的值,代码重复),难以维护。由于某些奇怪的原因,人们将单元测试视为劣于"真实"代码,并且根本不在乎其质量。 :-(
回答
教我团队敏捷开发的人不相信计划,我们只写了最小的要求。
他的座右铭是重构,重构,重构。我了解到重构意味着"不提前计划"。
回答
在我从事测试驱动开发的几年中,我不得不说最大的缺点是:
卖给管理层
TDD is best done in pairs. For one, it's tough to resist the urge to just write the implementation when you KNOW how to write an if/else statement. But a pair will keep you on task because you keep him on task. Sadly, many companies/managers don't think that this is a good use of resources. Why pay for two people to write one feature, when I have two features that need to be done at the same time?
卖给其他开发商
Some people just don't have the patience for writing unit tests. Some are very proud of their work. Or, some just like seeing convoluted methods/functions bleed off the end of the screen. TDD isn't for everyone, but I really wish it were. It would make maintaining stuff so much easier for those poor souls who inherit code.
维护测试代码以及生产代码
Ideally, your tests will only break when you make a bad code decision. That is, you thought the system worked one way, and it turns out it didn't. By breaking a test, or a (small) set of tests, this is actually good news. You know exactly how your new code will affect the system. However, if your tests are poorly written, tightly coupled or, worse yet, generated (cough VS Test), then maintaining your tests can become a chtheitroad quickly. And, after enough tests start to cause more work that the perceived value they are creating, then the tests will be the first thing to be deleted when schedules become compressed (eg. it gets to crunch time)
编写测试,以便涵盖所有内容(100%的代码覆盖率)
Ideally, again, if you adhere to the methodology, your code will be 100% tested by default. Typically, thought, I end up with code coverage upwards of 90%. This usually happens when I have some template style architecture, and the base is tested, and I try to cut corners and not test the template customizations. Also, I have found that when I encounter a new barrier I hadn't previously encountered, I have a learning curve in testing it. I will admit to writing some lines of code the old skool way, but I really like to have that 100%. (I guess I was an over achiever in school, er skool).
但是,我要说的是,TDD的好处远远超过了一个简单的想法的负面影响:如果我们可以实现一组涵盖应用程序的良好测试,但又不那么脆弱,以至于一次更改可以破坏所有这些测试,我们将能够像在第1天一样在项目的第300天继续添加新功能。这并不是所有尝试TDD的人都认为这是所有错误代码中的神奇子弹,因此他们认为可以工作,期间。
我个人发现使用TDD可以编写更简单的代码,花费更少的时间来讨论某个特定的代码解决方案是否可以工作,并且我不担心更改任何不符合以下条件的代码行:团队。
TDD是一门很难掌握的学科,我已经从事了几年,但我仍然一直在学习新的测试技术。这是一笔巨大的时间投资,但是从长远来看,与没有自动化的单元测试相比,可持续性将大大提高。现在,如果只有我的老板能弄清楚这一点。
回答
一切都很好。我将添加一些方法来避免TDD的阴暗面:
- 我已经编写了应用程序来进行自己的随机自检。编写特定测试的问题在于,即使我们编写了大量测试,它们也只能涵盖我们想到的情况。随机测试生成器会发现我们没有想到的问题。
- 大量单元测试的整个概念意味着我们拥有的组件可能会进入无效状态,例如复杂的数据结构。如果我们远离复杂的数据结构,则要测试的东西要少得多。
- 在应用程序允许的范围内,请避开依赖于通知,事件和副作用的正确排序的设计。这些很容易掉落或者混乱,因此需要进行大量测试。
回答
在测试所有代码之前,我们将失去说自己"完成"的能力。
我们将失去在运行之前编写数百或者数千行代码的能力。
我们会失去通过调试学习的机会。
我们将失去不确定的代码发布灵活性。
我们失去了紧密耦合模块的自由。
我们将失去跳过编写低级设计文档的选项。
我们将失去每个人都不敢更改的代码所带来的稳定性。
我们失去了"黑客"的头衔。
回答
开发时间增加:每种方法都需要测试,并且如果应用程序具有大型依赖项,则需要准备和清理数据以进行测试。