虚拟座谈会:代码测试比率、测试驱动开发及行为驱动开发
一直以来,TDD被公认为是一种(代码)设计准则、测试准则或沟通工具。然而,在TDD方法中,作为这些准则和工具的目标是如何影响设计的?在测试方面,TDD现在与未来的价值又是怎样的?让我们再回到问题本身,我鼓励大家去思考为什么你们需要做TDD,想想你的理由。不要限于典型的实施TDD与BDD的理由,例如:更好的设计、更少的程序缺陷、更有商业价值的产品特征以及更少的无用功。我鼓励人们多思考一下驱动你这样做的原因,这才是重中之重。我相信你会发现,一旦你采用了这两种方法,必然能按时完成分配的任务,因为这会让你更有条不紊,而不是到后来手忙脚乱。当然,我认为这些理由是因人而异的。我赞成以下说法:只要能够提交合格的代码,那么每个程序员或配对编程的人员就都有权利以他们所偏好的方式交付软件。如果他们打算使用TDD,我们就应该支持他们这样做。如果他们打算做些其他的,只要团队成员没有问题,我们也可以允许。Ron:我多希望在过去的半个世纪的开发生涯中,我能够在每个项目中都运用这两种方法。我并没有发明这两种方法,我只是最早接触的那几个人之一。TDD和BDD让我确信,没有更好的方法了,这两种方法也让我的代码缺陷数量大大降低。并且,当我更好地了解到系统或产品该设计成什么样子时,我的设计就更得心应手了。我从未在不是我编写的测试上获益,我也不认为这会对我所工作的项目有什么样的帮助,或是对TDD实践者的基本规范有什么样的贡献。对此我有所顾虑,就好象合同工走进要装修的房间,然后对之前的装修出言不逊。Ron:TDD会用到测试,但不仅仅是测试而已。它是我们开发系统的方式,是所有测试和程序的骨架。TDD以及其他相关实践让我们逐步地、一个特征接一个特征地开发系统。从始至终,它保证了代码的活性,以及可塑性。这让我们更清楚地了解我们究竟完成了什么,也让产品负责人或管理者清楚下一步要做什么,不论是通过揭露代码满是缺陷,或者设计是错误的,或者我们不能太快地改进。这也极大地减少了在项目最后阶段才了解到坏消息的可能性。我不认为这些目标是独立的。好的软件开发,需要整合很多想法,也需要我们平衡很多目标。我们并不想放弃这些,相反,我们希望能够找到一种方法服务于所有的目标。而这一切,让开发产品变得更快捷。Steve:当发觉沟通决定着其他方面的结果时,我必须强调所有级别测试中的沟通因素。例如:如果我致力于把一个测试用例写得可读性很高,这真的也能帮我发现对象引用的不恰当。 我见过很多团队陷入过维护性很差的测试用例的泥塘,而从拖累了整个进程。特别是在新的理解或概念出现的时候,你必须像对待生产代码一样(甚至超过)谨慎地对待测试代码。JB:在团队实践TDD一到两年的时候,我不停地接到团队的消息,向我倾诉测试成本与收益的不平衡。每次这种情况发生,往往是因为团队尝试用较大的测试集(集成测试,系统测试以及端到端测试)去检验较小的事情(独立对象的具体行为)。这往往会导致更大的测试套件,更频繁地运行测试套件(一个失败意味着23个测试失败),也会降低程序员维护测试用例的信心和兴趣。这样的测试,反而会给项目带来负面影响。这就是死亡行军(译注:越做错越多,越无法收拾)。当然,有些人或产品也能侥幸活下来。但遗憾的是,花如此大的时间和精力活下来,会让团队以为,所有项目都必须这样完成。(译注:感触颇深,同时有过3个项目,我带2个,另一个PM带一个,我的项目成员几乎不用在UAT前加班,氛围也非常好;另个项目天天加班,士气低落,民不聊生)。这才是大错特错!在有更好、更简单的选择的时候,他们几乎将自己逼进绝路。JB:正相反,如果组织重点关注在这些目标,那么就无形中创造出灾难的、会受到炮轰的成熟模式。你懂的:级别1表示我们写测试;级别2表示我们为所有新代码写测试;级别3表示我们对系统做50%的覆盖;我假设级别5表示我测试故我在。我认为这是没有意义的事情,我可以做这些,但结果还是交付了垃圾的产品。我觉得这是对我所教和我所崇尚的实践的一种嘲讽。Dan:我认为教条式的代码测试比率恰巧有着相反的作用。这意味着所有的代码都是同等重要,具有相同的风险,这样的想法是错误的。相反,我提倡对不同的代码,采用不同关注程度及审查力度的测试。任何企图达到代码统一的测试覆盖率的机会成本都是疯狂的,特别在用户接口测试方面。把时间和精力放到改进需要重点关注的代码的质量上,会更加行之有效,立竿见影。第二,我强烈建议团队分析测试覆盖和这类信息,这样才能更好地决定什么需要改进。人无完人,但我们必须警觉,如果发现了缺陷,那么我们就需要回顾所发生的情况,补充漏掉的测试用例,保证将来不再发生。Steve:我还是认为,在数据和划分不清楚之前,这是评价会有失精准。代码覆盖率有用,但作为外部的、过分强调的目标,也会影响团队应有的关注程度。Ron:好吧,我认为这是人类沟通的方式。这个世界上并不存在一种每个人听到都能理解的、清晰的语言。在我们边学边成长的商业世界,差异是不可避免的。在我眼中,最重要的差异是人们花很少或不花力气去理解这是些什么东西。相反,他们要么没有理解就开始诋毁这些建议;要么就是没有真正地去运用这些建议或没有理解地去运用这些建议,只是宣称他们在做这些。JB:没什么特别的。多多地实践那些技术吧,因为你希望它们能指导你改进工作。去做吧,因为这能给你个人成功。去做吧,只因它能帮助你更好地享受你的工作。总之,无论什么原因,去做吧!Ron:尽管我会在项目中运用其他方法,但在半个世纪里,我所用的所有方法中,这些是我见过最好的方法,虽然我不会强迫每个人都去使用。然而,我将做的是,我会建议关心这方面专业的每个人都能学习如何去运用这些技术到一个很好的程度,然后拥有能够决定何时、何处使用它们的能力。在能够对某种技术进行客观的评测前,你不该去回避这种技术。Steve:较常见的是,我所看到的关于TDD的主要问题,都不是测试难题,而是基本设计技巧的缺憾;人们之所以对测试比较纠结,是因为代码有着错误的结构。类似地,我看到过代码不能表现清楚。我越来越觉得,程序员的面试应该包括一个测试预选者编写一段可读性强的段落的测验。