大型 Android 系统重构实战
黄俊彬
Thoughtworks 资深咨询师
2840 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 29 讲
大型 Android 系统重构实战
15
15
1.0x
00:00/00:00
登录|注册

03|测试落地:三招提高遗留系统代码的可测试性

你好,我是黄俊彬。
上节课我们介绍了开发新特性时需要用到的小、中、大型自动化测试实践,也认识到了自动化测试的重要性。自动化测试不仅可以帮我们提高效率,还可以提高软件的质量。
但是,当我们面临一个没有任何自动化测试的遗留系统时,该如何落地自动化测试呢?这里面有一个绕不开的问题,就是如何提高遗留系统代码的可测试性?
我想这些场景你应该不陌生。
代码将所有的逻辑都堆砌在一个方法内部,很难模拟测试数据进行测试。
系统直接依赖外部的服务,测试执行耗时长、不稳定。
陷入“代码不可测就不写测试,然后不写测试又加剧代码不可测”的循环之中。
……
这也是为什么我们说遗留系统可测试性低的原因。对于这些场景,我们很难按照上节课介绍的方法直接覆盖中小型自动化测试,所以这个时候我们要先用一些特殊的招式来解决代码不可测的问题。
结合这个思路,今天我将给你分享解决遗留系统代码不可测的三个大招。

第一招:暴露接缝,“水到渠成”

《修改代码的艺术》一书中提到了“接缝”的概念。接缝是指在不修改代码的条件下,可以改变代码行为的地方。那么这个接缝和代码可测性又有什么关系呢?通常,设计一个测试用例需要三个关键步骤。
第一步,准备测试数据。
第二步,触发被测试的方法或行为。
第三步,断言程序执行的结果和用例设计预期是否一致。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

三招提高遗留系统代码的可测试性,包括暴露接缝、测试替身和模拟UI操作。暴露接缝通过提供可设置不同测试数据的接口,提高代码的可测试性;测试替身技术可以替换被测系统的依赖,隔离被测试代码、加速测试执行、确定执行变更、模拟特殊情况,从而让测试代码覆盖得更全、执行得更加高效稳定。文章通过具体代码示例和实际场景分析,帮助读者理解如何应用这些技术来提高遗留系统代码的可测试性。 在解决遗留系统代码不可测的三种方法中,作者提出了针对遗留系统的测试策略,建议首先考虑覆盖中大型的测试,然后进行代码重构;重构完成后再及时补充中小型的测试;最后逐步将自动化测试的比例演化为金字塔模型比例。这一策略为解决遗留系统代码可测试性低的问题提供了实用的指导。 通过本文,读者可以学习到如何暴露程序的接缝、使用测试替身技术以及制定测试策略来提高遗留系统代码的可测试性。这些方法可以帮助开发人员更好地落地自动化测试,尤其对于遗留系统的代码重构具有实际指导意义。 总的来说,本文通过深入的技术讨论和实际案例分析,为读者提供了解决遗留系统代码可测试性低的问题的有效方法和策略,对于开发人员和技术团队具有一定的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《大型 Android 系统重构实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(6)

  • 最新
  • 精选
  • liner
    有代码仓库吗,又可以运行演示的代码吗

    作者回复: 02的自动化测试有对应的演示代码,可以直接执行:https://github.com/junbin1011/AutoTest 后续的重构案例也都会有对应的代码,期待一起完成专栏的学习🤝

    2023-02-15归属地:广东
    4
  • 蓝色之海
    老师,使用 Ui-Automator 和 Espresso 无法获取到 Dialog 中的 UI 元素,我在网上查了很久也没找到解决方案,老师有遇到过类似的问题嘛?如何解决的呢? 我们工程中是实现了一个 Dialog 的子类,通过创建子类实例,然后执行 show 方法来显示 Dialog 的

    作者回复: Hi,这个问题我之前也没遇到过。我在YouTube看到有一个专门介绍测试Dialog,你可以参考一下看看有没有帮助。 标题:Dialog Input Testing (Material Dialogs) (Espresso for Beginners PART 10) 地址:https://www.youtube.com/watch?v=HRRn6m5hUoA

    2023-03-13归属地:广东
    2
    1
  • 墨水
    遇到可测性很低的项目,主要是被测试的类依赖于第三方服务\网络访问,但没有裂缝,无法使用测试替身或者Mock+stub的方法测试

    作者回复: 这个时候就需要先进行重构,你可以继续看看后面章节介绍的方法。

    2023-07-06归属地:广东
  • wh
    老师,请问下 Observable.from 导入的什么包?我点不出来。报错

    作者回复: Hi,wh。Observable是rxjava的库,需要导入对应的依赖。 具体使用可以参考:https://github.com/ReactiveX/RxJava

    2023-02-24归属地:广东
  • York
    老师,我们在重构系统的时候,打算前后端一起重构,前端页面也做了新的设计和布局。这个时候,我们又有什么好办法保证核心业务逻辑的正确?之前想通过对比新老API返回的数据来验证,但是我们也打算对返回前端的数据结构重新设计整理,所以感觉这个也行不通。请教下老师有没有什么好的建议。谢谢

    作者回复: Hi,York。非常开心收到你的留意。 从问题描述上来看,我们的产品的改进会涉及到如下2点: 1. 前端的页面会做新的UI涉及和布局 2. 接口会做新的结构调整 这里我猜测后端的接口调整,应该主要是补充一些数据,或者合并一些接口。建议任然可以通过编写自动化接口测试的方式来对比新老接口的数据差异(当然新增或者合并的数据需要编写脚本去处理)。 对于前端来说,如果之前的架构设计比较合理,主要是UI调整,那么涉及的修改主要也是在视图层,修改的风险相对比较可控。但如果之前架构耦合比较严重,那么得考虑先进行架构重构,进行分离。具体的方式和流程我们会在后续的课程中讲解,期待一起完成专栏的学习🤝。

    2023-02-20归属地:上海
  • peter
    请教老师两个问题: Q1:第二招的“Mock+Stub”有点不太理解。 文中有这句:“这种方式是用 Mockito 框架来 Mock 一个 LoginService 的假实现,然后进行 Stub”,从这句话以及其对应的代码来看,是用Mockito框架来模拟LoginService,即模拟被测试对象。但表格中对Mock的解释是“将所依赖的对象替换为。。。”,即Mock是模拟依赖对象,在登录的例子中,LoginService是被测试对象,其中的网络服务是依赖对象,所以Mock应该是模拟网络服务。似乎有点矛盾啊。 Q2:专栏的示例代码是用Java还是kotlin?

    作者回复: Hi,Peter。非常开心又看到你的留言。 Q1: 这里其实可以理解为LoginService就是代表着对应的网络服务,被测试对象也是依赖对象。 Q2:大部分为Java代码,也有一部分为kotlin代码。 期待你的下一次留言🤝

    2023-02-15归属地:北京
收起评论
显示
设置
留言
6
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部