电竞竞猜平台哪个靠谱[ZZ]如何锲而不舍TDD:使用者现身的题目以致应用方案

作者:web前端    发布时间:2019-12-21 23:49     浏览次数 :

[返回]

在敏捷开发中有很多好的想法和实践,这些想法和实践都非常管用:把项目分成小版本发布来进行风险管理和加速回馈;用时间盒并让所有人团结一致集中在项目中;仅依靠软件来作为进程度量;进行简单的估算并使用速度来预测团队的表现;和客户保持频繁而紧密的合作;持续集成持续发布以保证代码始终稳定可运行。但是还有一些别的并不是那么重要但被很多人接受的想法和实践:就算你不遵守这些想法和实践你的项目依然可以圆满成功,也不会有糟糕的事情发生。但是有一些想法实践你最好不要去遵守。测试驱动的开发做快速开发的团队需要依赖于一个快速高效测试安全网。在一个测试先行的或者是测试驱动的敏捷开发中,没有任何借口可以不写测试用例。在你开始编码前你必须先写好测试用例,然后你就可以采用一些高效的自动测试工具来保证有一个高水平的覆盖测试和回归测试。TDD不仅仅是一种供开发人员测试他们代码的保证手段,它更重要的一种开发技术,这种开发技术能够得到更高质量的代码和一个简单整洁的设计。微软和IBM的研究团队发现,虽然TDD增加了15%-35%前期成本,但是跟没有采取单元测试的团队相比缺陷密度降低了40%或多达60%-90%。但是在软件制作第12章“测试驱动开发的有效性有多好”中,由Burak Turhan主导的研究表明虽然TDD表面上提高了质量并且可以提高测试的质量,但TDD并不能一直提高设计质量。TDD似乎可以降低代码的复杂度,提高代码的重用率,但是它也能给耦合内聚带来负面的影响。虽然使用测试驱动的开发可以使得方法级和类级的复杂度降低,但包级和项目级却为之变得更加复杂。喜欢TDD的人为之疯狂,如果你也热衷于TDD,那就尽管用它吧。就算你对TDD并不那么感冒,测试先行非常自然的场景也是时不时出现——尤其是当你不得不通过一种特殊的方式来解决一个特殊的问题,或者你要修正一个bug而测试用例已经为你写好的时候。但是更重要的是,你要写一组很好的测试用例不断更新并且时不时运行它们,这跟你在写代码前还写写好代码后没有关系。结对编程根据VersionOne State of Agile Development Survey 2012(敏捷开发调查状况2012),几乎有1/3的团队采用了结对编程的开发方式——这是一个出乎意料的高数字,这显示出结对编程的良好的组织纪律性,同时表明有很多的团队使用了可以进行结对编程的XP和Scrum/XP方法。有采用结对编程的非常好的理由:开发人员一起工作可以通过持续的非正式的审查来提高代码质量和进行信息共享。让开发人员结对或者让开发人员和测试人员结对来一起工作的情况非常常见,尤其是当你在解决一个非常困难的设计问题,或者你碰到一段以前从来都没有接触过的代码而以前开发过类似代码的人就在旁边可以请教,或者你碰到了一个高压力的问题需要解决为此你豪无头绪,或者你在测试系统的一个非常难的部分,或者你的团队又加入了新的成员而这些成员需要基础学习的时候。一些人非常喜欢结对编程,喜欢它提供的非常强大的能量和非常难得的认识团队其他成员的机会。但是去强迫那些更喜欢自己单独工作的人去和自己不喜欢的人进行紧密的合作,这显然不是什么明智的作法。结对编程要花费社交成本:和一些有能力的,技术强的,有工作经验的,有自己独特方式的,有自己鲜明个性的或者是有自己职业道德的人一起结对编程你需要非常小心。而且长时间的结对编程让人精疲力竭——一项研究发现人们通常一天只结对编程1.5至4个小时,因为成天的结对编程工作强度太大以致于无法接受。在结对《编程或许是有害的》一文中,Jon Evans说结对编程对创造力有负面影响:引用研究强烈支持这个观点:当在享受更多的不被打扰的自由和隐私空间时,人们才有最好的创意......区别表现突出的大公司的开发人员的并不是更丰厚的工作经验和更高的薪酬,而是他们可以享受的不被打扰的自由的私人空间。”一篇纽约时报的文章大骂结对编程这种所谓“新的集体思维”时这样说。另外在Pete McBreen的“依然质疑极限编程”中指出了一些结对编程的其他缺点和弱点:不鼓励钻研思路,结对编程时开发专注编写代码,所以除非有一天的时间来钻研团队代码才能对代码有一点肤浅的理解。开发变得过度依赖单元测试,假如测试通过了,那么代码就OK了。没有进行详细的极端测试和边缘测试研究,特别是如果他们很难写出测试。当结对编程时很难做到经过详细思考设计的编码,除非另外一个搭档完全控制这个编码过程。通过平时搭档间的权衡,很难建立技术复杂的设计,除非他们已经确定了一个独自会话。结对编程时的个人风格问题,并不是所有的结对者都能像其他人一样。和打字技能、熟练程度不同的人结对编程,往往会导致打字技能好的人完成全部的编码而其他人变得完全被动。在分布式团队中结对编程显然也不会有效,即使这样,一些人仍然在尝试。虽然结对编程相比独自编程提高了代码质量,你也可以通过较低代价的代码复审来获得同样的代码质量提高,并且还有一些信息共享的优势。代码复审——特别轻便,离线复审——比结对编程更容易安排,代价更低点并且没有打扰。就像詹森科恩指出的那样 即使开发们结对编程,你或许仍然需要代码复审, 因为结对编程确实是共同解决问题,但是它并没有包含所有代码复审所涉及的全部问题。还是乔恩埃文斯关于结对编程的老话:引用真正的答案是有没有答案:独自编程,结对编程还是小组合作要根据环境用你最好的判断来动态结合才是最有效的。 结对编程的确有它存在的意义。在某些情况下,甚至是“绝对对的”。但是坚持100%结对编程是盲目的教条主义,和所有的盲目教条主义一样,最终只会适得其反。紧急设计和隐喻增量开发管用,而且尝试保持设计简单感觉起来不错,但试图飞速定义一个架构是愚蠢且不切实际的。几乎没有人遵循紧急设计有一个原因:它不管用。依赖于高水平的隐喻 (系统是一条 "流水线"或 一个"物料清单"或 一箱"蜂箱的蜜蜂") ,这些隐喻被团队共享为某种 代替建筑 是更加荒谬的。 卡内基梅隆大学基金会 的研究显示:引用… 自然语言的隐喻,无论对技术和非技术项目成员之间增进沟通,还是在开发架构方面,相对来说都不是很有用。总之几乎无人理解系统隐喻是什么 ,或者它怎样使用,或者怎样选择一个有意义的隐喻,或者如果你搞错了又怎样改变它,其中有人提出了这样的想法:引用好吧我还是不妨公开说出来 —— 我仍然不能找到这种隐喻事情的窍门。我发现它管用,而且在C3项目中工作的很好,但这并不意味着我知道怎么做,更不要说如何解释怎样做到了。 ——Martin Fowler, 设计灭亡了吗?敏捷开发方法促进了开发的成功率,并且展现出处理许多不同软件开发问题的更好方法——但不是架构和设计。每日站立会议当你有了一支新的团队,而每个人都需要相互了解,并且需要更多的时间理解项目是关于什么的;或者当这个团队迫于超级压力,正在试图修复些什么或者结束些什么的紧急的状况,那么将大家聚集起来开工作例会,甚至也许一天超过一次,这是必要的且有价值的。但是每个人是站还是坐,最终他们在会议上讨论些什么,将由你决定。如果你的团队已经合作一段时间也合作的很好,而他们每个人都互相了解并且知道他们在做的是什么,如果开发人员做完事情的时候,在任务板或看板上更新卡片,或者在一个电子系统里更新状态,如果他们足够成熟可以在需要的时候请求帮助,那么你不需要每个早上在房间里 让他们都站着。集中式代码所有权让每个人的工作都涉及到所有代码并不总是有效,并且集中式代码所有权对代码质量有负面影响。共享代码看起来似乎更有意义,但事实上却是不是每个人或者是应该为系统的每一部分工作。像写故事一样编写需求每一个需求规格说明都能以用户故事的方式,以1到2行写到卡片上的想法,需求应该简明扼要,坚持他们应该应该以相同形式的模板引用作为某一类用户,我有目标期望因此某些问题……是非常愚蠢和没有必要的。在15年前,这同样是一类简单而又传统的想法,让每个人都用 UML的用例的形式试图去捕捉所有需求。有更多不同的方式来有效的表达需求。有时候需求需要被规定到细节级别。有时候从一个测试用例或者一个具体的用例场景或一个框架或一切别的类型的模型开始会更有效,因为这样会让人知道如何推进,并且有些细节已经就绪。因此,运用格式化和细节层级能更有效也更容易开展工作。对产品所有者的依赖依赖作为产品拥有者的人,当项目失败的时候,就如客户唯一的声音和“一个发不出声音的喉咙”,无法扩展,无法持续,将团队和项目以及事实上的业务推向风险的边缘。很自然的,危险逐渐靠近正在设计的产品和管理中的开发项目,将比解决危险带来更多的问题。一些团队意识到这一点,并试图与产品所有者的想法保持一致,因为他们必须这样做。为了成功,一个团队需要在各个层次的真实而持续的客户合同,他们需要对自己负责,为确保他们得到他们所需要的,而不是依赖某一个人去完成所有的一切。英文原文:7 Agile Best Practices that You Don’t Need to Follow / 译文:开源中国社区

敏捷实践已经获得了越来越多软件公司的支持和推广,但是Jim Bird最近在一篇文章中指出,某些敏捷最佳实践其实可以无需遵循,因为它们不会给你带来太多好处,有时甚至是负面影响,这些“不重要”的实践包括:测试驱动开发、结对编程、每日站立会议等。

作者 Mark Levison译者 张晓庆 发布于 2009年2月3日 上午2时11分

测试驱动开发

我们组织里曾有许多团队努力采用测试驱动开发(TDD)[1]。偶尔会有一两个开发者成功,但是大多数都失败了。为了更好地找出原因,我调查了团队 的一些成员,发现即使经过了课堂培训,还有更多的事情需要做。虽然这里介绍的问题和想法只适用于中大型的公司,但理解这一点能够帮我们在组织中更好地引入 TDD。

做快速开发的团队需要依赖于一个快速高效测试安全网。在一个测试先行的或者是测试驱动(TDD)的敏捷开发中,没有任何借口可以不写测试用例。在开始编码前你必须先写好测试用例,然后就可以采用一些高效的自动测试工具来保证有一个高水平的覆盖测试和回归测试。TDD不仅仅是一种供开发人员测试他们代码的保证手段,它更重要的一种开发技术,这种开发技术能够得到更高质量的代码和一个简单整洁的设计。

我对组员(他们全都接受过培训)的调查显示,以下问题影响了他们:

微软和IBM的研究团队发现,虽然TDD增加了15%-35%前期成本(TDD要求开发人员改变他们的想法和工作方式,这减缓了他们的的开发速度,至少在一开始他们的开发速度慢了很多),但是跟没有采取单元测试的团队相比缺陷密度降低了40%(IBM)或多达60%-90%(微软)。

  • 由于经验不足,大家发现自己直接TDD比较困难。  
  • TDD培训的例子比实际应用简单得多。  
  • 需要更多的时间来实验和尝试,不要有赶紧发布软件的压力。  
  • 实际中应用的语言,比如Visual Basic和JavaScript,在单元测试文档或者课堂练习中从来不会用到。  
  • 常常会碰到很多遗留代码,而培训时不会介绍如何改进这些代码。  
  • 永远没有足够的时间用来学习──随时都有尽早交付产品的(人为的)压力,于是没有时间学习提高自己。

由Burak Turhan主导的研究表明虽然TDD表面上提高了质量并且可以提高测试的质量,但TDD并不能一直提高设计质量。TDD似乎可以降低代码的复杂度,提高代码的重用率,但是它也能给耦合内聚带来负面的影响。虽然使用测试驱动的开发可以使得方法级和类级的复杂度降低,但包级和项目级却为之变得更加复杂。

隐藏的问题

我们已经列举了这么多症状,那么冰山下面隐藏的问题是什么呢?

测试驱动开发并不是很难学。学习阶段(指形成根深蒂固的习惯的这段时间)一般会持续2到4个月,期间生产效率有所降低[2]。最终的好处显而易见,开发者也能自己保持该项技术,但问题是:怎么才能做到这样?很多开发者仅仅几天之后就放弃了。

就我见过的方法而言,大多数依赖于课堂培训(或者e-learning)和一对一的辅导。如果做得好的话,这些方法当然不错,可以作为整个解决方案的一部分,但是我认为还需要更多的方法。

课程培训有两个主要的问题:例子太简单,与实际问题关系不大;给大家练习的机会不多。

在线培训(Object Mentor和Industrial Logic,以及其它机构提供的培训),其优点是更有深度。然而练习的机会仍然不多。而且在这些课程里,你与其他学生通常没有交互。听一听你同学和同事的问题,能够加深你的理解。

一对一的辅导只能用于团队中的几个人,很难推而广之。在大型企业里面,专家只有几个,而需要帮助的人有成千上万,所以一对一的辅导更是困难。

看书是个很好的方法,但是很少有开发者喜欢通过读书学习TDD技术,即使有些人发现看书可以缓慢提高其TDD水平。与其它在线教程类似,看书仍然是只能一个人学习。

最后:遗留代码使得TDD难上加难。开发者当然会问这样的问题:“这些对象紧密耦合,怎样才能测试它们?这些代码太复杂了,怎样才能测试这个算法?”

结对编程

一个解决方法

那怎样才是好的解决办法呢?前面的方法主要有两个问题:没有深度、缺乏协作。一个完整的解决方案需要结合使用多种学习模式,并需要包含以下多种因素。

  • 课堂培训——开发者需要对TDD有个基本的理解,对多数人来说,课堂培训仍然是最好的方法。但是需要知道的是,培训本身并不能让人学会并使用TDD。  
  • 在线培训——这有助于加深基本概念的了解。但在所有这些方法中,这一种是可选的。  
  • 耐心——学习并使用TDD需要花费一定的时间,这个时间可能比你计划的更多一些。  
  • 衡量测试覆盖率——使用代码覆盖工具(比如Emma、Cobetura、NCover...)并向组员说明,衡量覆盖率可以让我们知道是否变得好些了,还是变得更糟了。很明显,这没法衡量测试的质量,因此只能用作参考。  
  • 内心感到自豪——开发人员需要知道什么样的代码和测试才是简单的、干净的,并需要感到花时间那么做是值得的。Bob Martin刚刚写了一本新书《Clean Code》,很好地回答了这个问题。  
  • 管理层的支持—— 开发人员需要管理层明确表态,说他们知道转向TDD会花费一定时间,并会“降低”团队效率[3]。他们需要澄清相对于产出速度和不断累积的技术债,他们更 看中的是质量。当不断地生产、生产、生产时,多数开发人员会有压力,所以管理层需要不止一次地重复这句话。说这句话的人等级越高(最好是来自最高层的执行 官),就会有越多的人去听。

 

  • 结对编程——如果你发现自己停滞不前、不知道下一步该做什么,与别人一块编程通常会有所帮助,即使他是个新手,也会使你受益颇多。  
  • 社区——在你的组织里(或者城市里)组建社区,大家互相分享经验。社区可以让你与其他正在学习使用TDD的人通过网络保持联系,可以让大家互相学习成功的经验和失败的教训,社区还能够培养TDD需要的文化。此外,社区提供了一个机会,让大家能够分享新的想法。  
  • 编程道场——是大家在一块练习解决小问题的地方。编程道场提供了一个安全、协作的环境,让大家作为团队一块研究问题,而没必要真正解决这些问题。  
  • 阅读工坊—— 一组人(不超过8个人)定期聚在一起,讨论书中的某一章节。  
  • 教练定期走访——当团队偏离轨道、终止实践TDD时,教练的定期走访能够帮助团队重回正轨。这时与一两个人配对编程,就能够重新感染整个团队。

这一计划的核心是:针对TDD创造交流机会、促进互相协作。以上方法中有3个是关注这一方面的:结对编程、编程道场和阅读工坊。

根据VersionOne的敏捷开发调查状况,几乎有1/3的团队采用了结对编程的开发方式——这是一个出乎意料的高数字,这显示出结对编程的良好的组织纪律性,同时表明有很多的团队使用了可以进行结对编程的XP(2%)和Scrum/XP(11%)方法。

编程道场

编码道场(使用自由方式)指的是这样一种活动,一小组人(最多15个人)采用TDD一块解决问题(下述内容来自Danilo Sato):

  • 在一个电脑上工作,通过投影让所有人看到输出结果。
  • 采用配对编程的方式。
  • 配对中的一个人每5到10分钟交换(我们用的是7分钟,效果不错)。
  • 编码的人要解释他们正在干的事情,这样观众才能明白他们在干什么。
  • 只有当测试通过时观众才能够对设计给出评论,而测试失败时观众不能提问题。
  • 如果观众被搞糊涂了,编码的人应该停下来解释他们在干什么。

根据经验,我建议初次尝试要选择一个很小的问题。

采用结对编程的非常好的理由包括:

阅读工坊

对阅读工坊来说,有很多好书可以选择:

  • 如果是Java项目: Lasse Koskela的《Test Driven: TDD and Acceptance TDD for Java Developers》;
  • 如果是.NET项目:Kent Beck的《Test Driven Development: By Example》;
  • 如果你已经学习了很多:Gerard Meszaros的《xUnit Test Patterns: Refactoring Test Code》;
  • 如果你不使用TDD:Michael Feathers的《Working Effectively with Legacy Code》。

典型情况下,团队在一次会议上可以讨论一章或者两章的内容。节奏一定要慢,让大家能够在业余时间读完相关内容,而不是变成了负担。除此之外,要留够充足的时间,让大家对文中的一些条目做深入地探讨。

下一篇:没有了