测试驱动开发与遗留代码的问题

发表于:2009-12-09 14:49

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Mark Levison    来源:InfoQ

#
敏捷
#
TDD

  Allan Baljeu试图在他庞大的、C++遗留代码库中使用TDD,结果遇到了很大的麻烦,因为:

  “我们后来得到的类不能完全实现希望其具备的功能,当有人使用这些类时,会想要得到更加完整的实现,然而却会发现原有的设计不够完善,要进行新的设计,有些期望(测试)要做出改变,而之前对这些类的使用也得调整。”

  他在思考前期大规模设计(BDUF)也许有助于解决这个问题。George Dinwiddie是敏捷教练,他认为Alan的设计是在试图告诉他些什么。人们必须要注意“干净代码(clean code)”的基本原则,要注意基本的内聚和耦合性方面的问题(比如SOLID原则)。

  Mike “Geepaw” Hill也是Agile Coach,他提到:在他指导敏捷团队的这些年来,下列原因之一可能是类似问题的根本原因:

  * 团队在重构方面做得不够,因此你的类没有做到最小化。

  * 团队在“尽量简单”方面的技能还不够,同样如此。

  * 团队还没有采取具备侵略性和快速度的微测试(microtesting,也就是单元测试),所以改变常常会破坏测试

  * 团队不知道如何处理跨团队、或是公司对公众之间的依赖,比如公布API的情况

  * 团队既没有结对,也没有在开放空间中工作,这极大降低了团队层面的知识理解和传递

  * 团队似乎没有具备快速构建的能力

  * 团队可能还在使用老古董级别的工具

  Keith Ray是极限编程教练,他提出:有了遗留代码(也就是欠下很高技术债的系统),实现一个故事的成本完全取决于偿还技术债的成本。接下来,他提出一种解决方式:

  “要让代码的结构更好(偿还技术债务),不管什么时候,当你需要集成一个新功能时,你应该同时注意新旧代码中的异味,并在发现异味时,马上重构,消除异味。

  你可以手工采取小而安全的步骤进行重构(即使使用C++)。要紧跟Martin Fowler《重构》一书中的步骤,除非你能做到得心应手。带有gcc的Eclipse有些重构功能可以使用:“抽取方法”和“重命名”。“重命名”能够知道命名所在的范围,所以要比查找和替换更为安全。“抽取方法”和其他的重构功能可能有bug,使用它们的时候要小心。像改变函数签名这样的东西,“依靠编译器”能够展示出哪里需要改变。

  你还需要测试来保证没有破坏现有功能。Michael Feather的《修改代码的艺术》提供了很多向遗留代码中加入测试的技巧。从更高层面来看,代码异味是破坏优秀设计原则的表现。举例而言:单一职责原则(SRP)认为:每个类、方法、模块只应该有一个意图。还有些原则是与耦合、内聚和管理依赖关系相关的。相比使用这些抽象原则,发现代码异味常常更为容易。“大类”和“大方法”可以通过“抽取类”和“抽取方法/移动方法”修改,不过知道SRP有助于判断抽取类或方法的哪一部分。

  也许“告知,不要询问”是最重要的设计原则:不要分离功能和数据……恶劣的代码常常把功能实现放在一个地方,从其他地方得到需要的数据,这就造成了依赖性方面的问题,同时代码缺少局部性(locality)。其症状就是:“添加一个新功能,要修改多处代码。”代码异味“散弹枪式手术”、“依恋情结”、“参数列表过长”都是这样造成的。

  尽快得到反馈能带来更多重构,这最终将会加快新功能的开发。尝试进行并行构建(分布式编译),尝试让源代码文件和头文件更小,降低头文件的复杂度——可使用前向声明、避免内联代码、尝试让每个类只有一个头文件/源代码文件。大量使用“指向实现的指针(pimpl idiom)”能降低10%的编译时间,但是也可能把“大类”和“依恋情结”这样的代码异味给隐蔽起来。

  重构要比重写更好,其优势在于:你总是有可工作的代码。如果你的手工和自动化测试都很好,那你就可以交付代码了,即使目前的状态处于“优秀设计”和“恶劣设计”之间。”

《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号