您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
Agile Alliance 单元测试—重构的守望者
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
Agile Alliance 单元测试—重构的守望者
自猿其说Tech
2021-01-19
IP归属:未知
44920浏览
敏捷测试
敏捷
计算机编程
#### 前言 **重构(Refactoring)**就是通过调整程序代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性。 **单元测试(unit testing)**,是指对软件中的最小可测试单元进行检查和验证。单元测试是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。 **在实践中重构与单元测试往往是密不可分的伙伴。**介绍讲解单元测试相关的资料,其中一般会有专门的章节来说重构。而阐述重构或者说代码优化相关的文章一般也会有单元测试的部分。 #### 问题的引入 每年的备战或者说面对线上问题,我们总是会对代码做或大或小的优化: - 调整代码的结构 - 精简冗余的部分 - 改变实现的算法 - 更改存储的结构 不过在动手之前,脑子里常常会有一个小人站出来大声的呼喊:冷静,改崩了怎么办? 小人的这个问题对于新代码新系统来说还好,大家熟门熟路,一切还在“掌握”中。而对于很多“历史悠久”的系统来说,文档的缺失、人员的变动再加上需求压力带来资源的捉襟见肘会使“掌握”的难度大大提高,在不清楚背景的情况下何保证逻辑的前后语义一致难上加难,小问题变成大心患。而单元测试就是你的好助手。 小人的问题的实质是要构建一个安全网,它可以对重构过程中的每一次的代码变更做出检验,及时的发现不一致的风险点。单元测试的种种特点正是这样的一种保障机制。 ![](//img1.jcloudcs.com/developer.jdcloud.com/2657d1bd-7141-4514-88b5-683a0de2cf5d20210119182929.png) **容易写单测的系统高内聚低耦合 难以写单测的系统则一言难尽**————图片来自网络 #### 单元测试的自夸 ##### 没有人比我更懂系统 文档不可靠。在部开发工作中经常视为规范的文档,它其实在推广的过程中有点种种的困难。比如说目前文档的载体不统一,cf?DOC?joyspace?不同的部门甚至不同的小组选择都会不一样。对于这些编辑工具来说的话,都存在着或多或少的组织上、表达上的缺陷。翻译一种语言,总有可能带来表达意思上的失真。不同的开发人员在文档的表达能力的不同也将此问题加剧。 人不可信。口口相传的只能是传说,要脚踏实地还得扒代码。即使维护了文档,及时性也难以保障。人员的变动,也会导致实际需要文档的时候总感觉与代码貌合神离。 **而单元测试用例是和需求代码在一起的。不求同生,但求同死。一旦提交,必会伴随着代码的整个生命周期。每当有新需求加进来,就要不断增加或者调整用例,保持自己的先进性。在表达语言上与需求代码保持一致,在及时性上保持一致,与需求代码紧密结合,不惧怕人员变动。** ##### 重构最需要"懂"! ##### 我不会占用你与熊孩子搏斗的时间 通常推广单测时遇到的最多的问题是:单测会增加工作投入,导致项目的延期。其实这是个伪命题,如果是刚推行单测,的确是如此,局部的工作增加了,但效果没有体现出来!但如果把时间拉长来看:**单测会减少开发的整体时间,而且会提高你投入时间的个人技能积累。** 先来思索下没有单测的情况: 开发完一个**初始需求** 调试本地启动环境至正常启动 找测试同学造单;在测试环境自行造数据;在数据库插一条测试数据。 验证测试结果;咦这里不行,我不信,改下数据再来一次;咦还是不行,改下代码,再改下数据,重发布一次;咦…… 提测 过了半年,另一位同学接到了一个**改造需求**,更改**初始需求**代码。 开发完成 调试本地启动环境正常启动 找测试同学造单;在测试环境自行造数据;在数据库插二条测试数据。(此时测试环境中已经没有初始需求的测试数据了) 验证测试结果;咦这里不行,我不信,改下数据再来一次;咦还是不行,改下代码,再改下数据,重发布一次;咦…… 提测 测试同学脑壳疼,之前的场景怎么跑不通。返工。。 可以预见到,经过多次的上线后,原来的初始需求的场景可能变的面目全非。没有单元测试的积累,无论是新接手的同事还是半年后的你,虽然能快速的把新场景开发完,但由于测试不充分,很可能在不经意的时候引入了改变之前场景的bug。这些bug不但会导致提测后的多次返工,花费更多的时间,还有可能在线上引发事故。 这种一次性的测试用例的另一个问题是,工程需要跑起来才能测试,这本身可能很费时间。有的工程重启一下10多秒,还好。但有些工程启一次可能4、5分钟,遇到反复修改,这就要了老命了。 还有,开发环境依赖的外部环境数据准备不充分,反复沟通这个也要费不少时间。无论是跟测试同学,还是跟其它依赖系统的同学沟通,节奏不能把握,进度自然无法保障。 如果是单元测试充分的团队,再次接到改造需求后,场景可能是这样的: 开发完成 跑一下之前的单元测试用例。咦,有问题,改下,再来一次。…… 调度本地启动环境,成功。 与测试、架构同学review单元测试用例。开发、测试恍然大悟,发现风险,补充用例。更改代码,再来一次。 提测 oh,yeah! 一次性的用例制作与写单元测试相比,不见得更节省时间。不用重复创建老场景的测试用例;不用多次的在重启中等待;不用到处沟通造数;节约生命,享受生活,岂不美哉! ##### 我可以是研发与测试沟通的桥梁 经常在听到开发与测试同学这样的对白: "这么多问题,你测过了没有。" "天地良心,刚测完, 代码还热乎着呢。" …… 争论的实质是测试用例对齐。即使进行过多次需求评审,开发、测试两者队对需求的理解可能仍存在着偏差。传统上开发提测时并不与测试讲解自己是怎么测的,自测的方式是否有效、是否真的测过都没有直白的证据。如果在代码review阶段加入测试用例的评审,自测用例不仅可以做为自测完成的证据,也能成为自测完整与否的沟通立足点。在review中及时发现开发与测试对测试完整性理解上的分歧,提前解决问题,减少提测后返工的巨大成本。 重构的过程中也是如此,产研测对齐用例提前暴露风险,降低线上出问题几率。 ##### 我很稳定,下次还能再见 这个其实在之前的例子里已经带过了。一次性测试用例的最大问题是不稳定。由于测试环境数据库、依赖系统的变更,下一次使用时存在与否都是个问题。造数的外部环境可能会清理,数据库可能会重装,开发电脑可能会故障等等…… 。一次性用例也很难在开发之间形成沉淀,导致重复使用上的困难。开发同学往往不清楚另一个同学是怎么设计、存储测试用例的。维护这样的规范,要考虑到多环境的稳定,这个在测试情景下本来就极不现实。 写单元测试相当于是一种约定,用一种大家都熟悉的方式将用例固化下来。每一次的变动都有追踪,每个人的用例都有归档,摆脱工具、介质的依赖。历经海枯石烂,你不在,它还在! #### 经验教训 在重构前编写单元测试,而不是重构后。用重构前的单测用例验证重构后的代码。 重构前弄清代码的逻辑是必须的,而单元测试就是最好的证据。 平时多留汗,战时少流血!平时跑不通的用例都说明了工程中不为人知的变化,让它跑通。 对于难以书写单元测试的代码,有总比没有强! 重构不是重写。重开一个副本未必能兼容“丑陋”代码所包含的场景,不易察觉的风险悄然发生。 单元测试很难一蹴而就,快递技术部自从去年开始坚持到现在,实现了绝大多数工程具备单元测试的能力,部分核心工程行覆盖率逐步达到40%以上。可以从新项目、新功能入手形成自己的规约,熟练后再逐步推广到老项目。 ------------ **主编的话:** 黄亮的这篇是我求来的“命题作文”,但却行云流水、生动活泼;想来平时对架构思考的多,思维也练的特结构清晰、逻辑有序!在文中他提到了“节约生命,享受生活”,我非常赞同;站在未来想一想,你的 Coding时光是投入在一次性的工作上对你的价值高,还是投入在能练习设计能力的工作上对你的价值高?聪明的你,一定会选后者吧。 ------------ ###### Being Agile 京东物流技术发展部效能提升部 ###### 作者:快递技术部 黄亮
原创文章,需联系作者,授权转载
上一篇:Agile Alliance 京驿货车的Flutter编码规范
下一篇:Agile Alliance 如何打造自运转敏捷团队
相关文章
前端DevOps流水线实践
Being Agile 单元测试认知篇
单元测试与重构
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
本文将从Optional所解决的问题开始,逐层解剖,由浅入深,文中会出现Optioanl方法之间的对比,实践,误用情况分析,优缺点等。与大家一起,对这项Java8中的新特性,进行理解和深入。
01
Taro小程序跨端开发入门实战
为了让小程序开发更简单,更高效,我们采用 Taro 作为首选框架,我们将使用 Taro 的实践经验整理了出来,主要内容围绕着什么是 Taro,为什么用 Taro,以及 Taro 如何使用(正确使用的姿势),还有 Taro 背后的一些设计思想来进行展开,让大家能够对 Taro 有个完整的认识。
01
Flutter For Web实践
Flutter For Web 已经发布一年多时间,它的发布意味着我们可以真正地使用一套代码、一套资源部署整个大前端系统(包括:iOS、Android、Web)。渠道研发组经过一段时间的探索,使用Flutter For Web技术开发了移动端可视化编程平台—Flutter乐高,在这里希望和大家分享下使用Flutter For Web实践过程和踩坑实践
01
配运基础数据缓存瘦身实践
在基础数据的常规能力当中,数据的存取是最基础也是最重要的能力,为了整体提高数据的读取能力,缓存技术在基础数据的场景中得到了广泛的使用,下面会重点展示一下配运组近期针对数据缓存做的瘦身实践。
最新回复
丨
点赞排行
共0条评论
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
01
Taro小程序跨端开发入门实战
01
Flutter For Web实践
01
配运基础数据缓存瘦身实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号