程序员的测试课
郑晔
开源项目 Moco 作者
18911 人已学习
新⼈⾸单¥59
登录后,你可以任选2讲全文学习
课程目录
已完结/共 23 讲
加餐 (1讲)
结束语 (1讲)
程序员的测试课
15
15
1.0x
00:00/00:00
登录|注册

16 | 怎么在遗留系统上写测试?

你好,我是郑晔!
迄今为止,我们讨论的话题主要是围绕着如何在一个新项目上写测试。但在真实世界中,很多人更有可能面对的是一个问题重重的遗留系统。相比于新项目,在一个遗留系统上,无论是写代码还是写测试,都是一件有难度的事。
在讨论如何在遗留系统上写测试前,我们首先要弄清楚一件事:什么样的系统算是遗留系统。在各种遗留系统的定义中,Michael Feathers 在《修改代码的艺术》(Working Effectively with Legacy Code)中给出的定义让我印象最为深刻——遗留系统就是没有测试的系统。
根据这个定义你会发现,即便是新写出来的系统,因为没有测试,它就是遗留系统。由此可见测试同遗留系统之间关系之密切。想要让一个遗留系统转变成为一个正常的系统,关键点就是写测试。

给遗留系统写测试

众所周知,给遗留系统写测试是一件很困难的事情。但你有没有想过,为什么给遗留系统写测试很困难呢?
如果代码都写得设计合理、结构清晰,即便是补测试也困难不到哪去。但大部分情况下,我们面对的遗留系统都是代码冗长、耦合紧密。你会不会一想到给遗留系统写测试就头皮发麻?因为实在是太麻烦了。由此我们知道,给遗留系统写测试,难点不在于测试,而在于它的代码。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文探讨了在遗留系统中编写测试的挑战和解决方法。作者指出,遗留系统的代码设计不合理、结构混乱,导致编写测试复杂。然而,要使遗留系统正常,关键在于编写测试。文章提出了在遗留系统上编写测试的实用方法,即根据对代码库的理解,有针对性地编写测试,尽量降低测试的层次,更精准地编写测试。解耦也被强调为在遗留系统中编写良好测试的关键点。通过提取方法、引入封装层和接口等重构手法,可以有效解耦业务代码和具体实现,从而实现更好的测试。总的来说,本文为读者提供了在遗留系统上编写测试的实用建议,帮助读者更好地理解和应对这一挑战。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《程序员的测试课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(12)

  • 最新
  • 精选
  • 大碗
    如果新加一个订单完成的业务,需要发布带订单orderId,finishedTime的订单完成事件,也是在sender里面加这个方法么?怎么设计会更好呢

    作者回复: 一种做法是定义一个模型叫事件,不同的地方发出不同的事件,至于 orderId、finishedTime,就是事件的参数。这样,sender 有一个接口就够了。

    2021-09-08
    7
  • 阿姆斯壮
    工作大多数场景是界面编程。想咨询一下校长,自己总感觉界面这块有点无法套进单元测试里面。也不知道那里欠缺了。

    作者回复: 现在的前端都有特定的框架支持了,比如,Selenium/Webdriver 测试前端界面,支持模拟界面上的操作,移动端也有对应的框架。不过,一般来说,前端一定要把逻辑和前端界面分开。这种框架对前端界面的支持,属于集成测试的范畴,而单元测试主要以测业务逻辑为主。

    2021-09-08
    2
    2
  • 闻人
    要让项目易于测试,写代码要注重隔离,实现与接口隔离,业务与外部组件隔离 #收纳盒 #极客时间

    作者回复: 其实就是做好设计

    2021-09-08
    2
  • 刘大明
    郑大,有个问题请教一下,如果每次重构的时候发现需要提取一些类,怎么将这些单独提取出来的方法放在合适的位子呢。比方说有一块重复代码需要提取出一个公共方法,这时候需要引用一个新的类,怎么知道这个类具体的名字,目前就是不管什么都放到factory里面。

    作者回复: 这其实就是一个构建模型的过程,取什么名字就是根据这段代码在做的事情,创建就是 Factory,发送就是 Sender,接受就是 Receiver,连接就是 Connector,如此而已。

    2021-09-17
    1
  • Geek_3b1096
    周五就遇到只有具体KafkaProducer没有接口没有测试

    作者回复: 现学现卖,幸福

    2021-09-12
    1
  • sylan215
    提取独立接口确实是个好办法,和这个类似的,还有提取同类项的做法,就是同一份代码被不同地方进行了拷贝,也是可以改为统一调用,让逻辑更清晰。 现实中对于老代码的维护,大部分碰到的困境是,因为需求,需要修改老代码,修改之后没法确认影响范围,就算做了单元测试,系统测试层面为了保险起见,也是要进行大面积的回归,这时候要是没有自动化,就很惨了,从这个角度说,好的代码设计和实现,就是好的测试。
    2021-09-16
    4
  • 独孤九剑
    “业务”是相对稳定的,依赖的“具体实现”是易变的,因此“解耦”是最佳实践。IDE提供的“3个提取”式重构功能是极好的。
    2021-10-21
    3
  • UncleNo2
    一顿操作猛如虎,如此顺滑,舒适感爆棚
    2021-12-03
    2
  • 6点无痛早起学习的和尚
    这里想到了,绝大部分面向接口编程的目的是为了屏蔽具体实现,具体实现也可以多扩展,调用方无感知。 但是实际上在工作中,一般持久化接口具体实现都是MySQL,所以就直接写类了,不面向接口,我们当前团队就是这样开发的,包括核心业务逻辑也是直接写类,不面向接口。 因为团队代码发展了好几年了,有些就不会扩展的具体实现,那就直接写类,不写接口,是不是也没有问题啊
    2023-05-02归属地:北京
    1
    1
  • 秃然的自我~
    从可测试的角度来讲,也就是构建一个可控的环境,依赖的KafkaProducer完全可以用Mockito框架模拟一个可控的对象来解决啊,不会影响单测 只是业务代码和具体的实现强耦合并不是一个好的设计
    2023-06-12归属地:北京
收起评论
显示
设置
留言
12
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部