zoukankan      html  css  js  c++  java
  • 遗留代码单元测试与重构的一点小体会

    遗留代码单元测试与重构的一点小体会

    前提

    近日由于项目需求,我前往另一团队协助其代码进行测试,初到团队,我被告知了一个要求“只添加测试,不要修改原代码,即使可能写的不好,除非是那些真看不过去的”。对于这个要求,先不提是否合理,它提醒了我一件事——先要尊重别人的劳动成果。这一点常常会被我们这些团队“外来者”忽略,被派驻到团队的我们,多少有些居高临下的意味。在我们看来,既然请我们来,一定是现有的工作状态有了问题,在占据了道义制高点后,我们对于团队现有的状态会觉得哪里都有问题,比如遗留代码,会产生一种到处都有“臭味”的错觉,即使代码真的是很有问题,在这种状态下,无法认同别人就会导致无法认真地理解代码,而是一味粗暴地涂抹别人的代码,时间长了就会陷入越改问题越多的泥淖中去,更有被团队成员孤立的危险,如此恶性循环,最终的结局很有可能是任务失败,更糟糕的是惹怒了整个团队,原因就是你凌驾于别人之上彻底旁路了团队,并且残忍地否定了团队之前的成果。

    为了防止这样的结果,不妨像我派驻的这个团队一样,先给我们自己心里留一条红线,时刻提醒自己:

    无论现在的结果如何,都要坚信这是当时情况下能够获得的最好结果

    一旦明白这点之后,就可以放开手脚干你想干的事,因为你的尊重换来的将是对方团队成员的诚心参与,他们会帮助你去了解代码,帮你去承认他们犯过的错误,帮你修正他们自己的过失。最后当回顾整个过程时,团队会发现所有的改进都是来自团队自己的努力,这才是最好的结果。

    实施

    纸上得来终觉浅,绝知此事要躬行 —— 陆游 《冬夜读书示子聿》

    测试是件很有意思的事,有意思是因为这件事看上去很简单,但操作起来却很不容易。任何一个参加过几次测试用例培训或是看过几本讲述测试书籍的人都会讲出好些有关测试的条条框框来,但事情有时候就是这样,越是看起来简单的事,越是不容易做好,尤其是面对遗留代码的时候,所有各式各样的测试技巧,只有落到代码上才能真正地体现作用。

    为何遗留代码做测试不容易,因为首先要会意,会意是个沟通过程,这个沟通包括与代码沟通和与维护团队沟通,后者比前者更重要,我很幸运,代码的原作者尚在团队中,所以沟通成本还不算高,只要遇到看不懂或是不明白的地方就记下来向原作者请教。

    会意,“意”很关键,刚开始先不要急于去添加测试,先坐下来,泡杯茶,请作者一起坐下来,请他(她)讲解下代码的流程,先从作者的角度去看代码,了解作者的意图,多问问为什么,让自己成为他(她)的徒弟,先别在意细节。接下来沿着作者的思路,试着自己去切割下代码,想办法先把代码分成几个大块功能,记录下来再向作者确认,在确认的过程中,逐步修正自己的想法达到与作者尽可能的统一。

    有了按作者意图切割的大块功能,现在要做的是跳出作者的思路,看看哪些功能块是可测试的,先从可测试的入手,重复上面的会意过程,仍然是切割,切割的是边界,边界将是测试的参考点,这个过程中,沟通仍然是重点。

    现在可以开始测试了,在开始添加测试之前,还有两件重要的事情要做:

    • 建立版本控制
    • 请作者和你一起

    为了保证不破环原有代码,必须要先有安全沙箱,也算给自己留条后路,别觉得麻烦,在很多时候它可以挽救你,抚慰你因为步子迈得过大而扯着蛋的疼痛。

    心若在,梦就在,天地之间还有真爱,看成败人生豪迈,只不过是从头再来 —— 刘欢 《从头再来》

    让作者和你坐到一起添加测试,很多时候作者会比你快一步给出测试的构造,特别是当他(她)在了解了测试的过程之后,甚至很快你就可以在一旁看着作者自己添加测试,而只是在必要的时候给他(她)一点有关边界场景的提醒。这就是为何应当坚持让作者和你坐到一起添加测试,从你的演示中,作者会了解到测试不是一件高深的事物,相反在掌握了一定的技巧后,甚至比开发简单,其实大多数时候,遗留代码没有测试是因为开发人员对测试存在误解,认为测试复杂不易掌握。让作者和你坐到一起添加测试的另一个重要原因是当你真的不得不修改原代码时,获得作者对修改代码的肯定是件十分重要的事,没什么比建立信任更重要了。

    做完这两件事,剩下的就是运用测试技巧了。

    特点

    遗留代码是面镜子,很多时候可以照出自己的臭毛病。遗留代码通常会有比较明显的如下问题:

    • 重复,许多看似雷同的代码
    • 耦合,责任不明确
    • 冗长,往往出现超长超大的类或方法
    • 晦涩,方法或变量命名随意性大,分支嵌套

    问题严重程度从上到下逐个降低,但是解决问题的顺序却是从下到上。

    晦涩,请作者和你坐到一块解决,只要遇到不明白的就向作者求教,再提出自己的建议,建议作者换一个更清楚的表达的方式;

    冗长,切割抽取,先向作者确认切割是否合理,然后在将切割后的各个部分抽取成方法,通常一个冗长的方法会被切割成三部分:入参校验、执行段,返回值;

    耦合,其实作者基本上帮忙做了,但是没做彻底,再物以类聚一下;

    重复,留待最后解决,需要作者一起去抽取逻辑,虽然被称为代码缺陷的万恶之源。

    成效

    其实写这篇文章时,我的任务尚未完成,只是在完成任务的过程中有了一点小小的体会,遗留代码的测试和重构不简单,却是很好的试金石,越是深入收获就越大,做的过程也是重新思考自己编码的习惯的过程,期待更多的体会。

  • 相关阅读:
    【NIO】NIO之浅谈内存映射文件原理与DirectMemory
    【搜索引擎】全文索引数据结构和算法
    【多线程】并发与并行
    【缓存】缓存穿透、缓存雪崩、key重建方案
    布隆过滤器
    多层路由器通信
    【路由】设置二级路由器
    【硬件】集线器,交换机,路由器
    JZOJ100048 【NOIP2017提高A组模拟7.14】紧急撤离
    JZOJ100045 【NOIP2017提高A组模拟7.13】好数
  • 原文地址:https://www.cnblogs.com/hxfirefox/p/4809984.html
Copyright © 2011-2022 走看看