【腾讯TMQ】测试左移之代码评审
2017-08-17 17:13
423 查看
导读
最近两年,品质中心极力推动测试工作左移,以期能提前发现产品的问题,降低成本。笔者自认代码基础能力还不错,就想通过代码Review来提前发现一些Bug。多数项目中,代码评审工作是由开发同事相互执行的。但往往开发同事为了赶进度,并没有时间进行代码评审,导致很多明显的Bug被遗留到了测试阶段。那代码评审是否可以由测试人员来做呢?显然是可以的。诚然多数测试人员的代码能力没有开发人员的水平,代码Review的深度不如开发同事,但通过实践证明,测试人员也能胜任大部分代码评审的工作。
做CodeReview的方法
笔者在刚开始做代码Review时也是毫无头绪,不知道哪些代码可能有问题。那时我才意识到了解Bug出现的根因对代码Review有至关重要的作用。通过对Bug及开发对应修改的代码进行分析,并与开发同事交流,我了解到一些Bug出现的原因,以及出错代码的一些特征。当这些代码特征被总结出来后,我将这种特征用于Review其他的代码,此时能慢慢地能发现一些Bug了,但效率比较低。
后来用Android Studio自带的Lint工具扫描代码可以扫描出大量疑似缺陷的点,再通过人工分析可以发现不少空指针和逻辑上的问题,Review代码的效率得到了极大的提升。
但还有一些更深层次的需求,比如像一些多条件组合的代码就不能通过Lint扫出来了。因此我把这些特殊的代码特征进行汇总,请一个同事帮忙写了一个定制化的代码扫描工具,利用这个工具扫描出代码位置,然后针对性的Review。
总结我的实践过程,建议刚开始做代码Review的朋友,先使用一些业界常用的工具快速入手。当积累一些经验后,尝试自己分析问题并总结经验,好的经验积累起来形成自己的知识库和工具库,提升Review效率。
Review知识点汇总
以下是笔者在平时工作中总结出一些经常可以发现问题的点,希望对同仁们有所帮助。1、空指针
如果项目有异常上报统计,就会发现最常见的异常是空指针异常(NullPointerException),代码中如果使用了未初始化的对象都会导致这个异常。一般开发都会在程序入口处进行参数的判空,不过这样还不够。严格意义上,任何一个对象在使用前都应该进行判空处理。如下代码片断所示,一些开发同事习惯当传入参数为空时,直接返回一个空的对象。单从本方法的角度来看是不会有问题的,但是在调用本方法的地方,如果忘记做判空处理就会出现空指针的错误。
以上示例中较好的代码实践是返回一个没有元素的列表,或者是当参数为空时直接显式的抛出一个异常,让调用者必须处理该异常。
针对空指针的情况,一般Review以下几点:
(1)方法参数如果不能为空时,是否做了判空处理,或者在方法调用者传入参数时是否确保了不为空;
(2)方法是否有返回null的情况,如果有是否可以改为返回一个空白对象(如没有元素的列表等);
(3)当被调用的方法(如系统方法)返回为null时,调用者是否有进行判空处理;
(4)使用的对象是否在使用时已经被初始化。较常见出现问题的情况是类的成员,如果在构造函数中没有进行初始化,而在其他地方进行初始化时,初始化时机是未知的,那么此时对象使用前一定要进行判空。
2、逻辑判断
(1)边界判断数组越界(OutOfBoundaryException)在异常统计上报中也是比较常见的问题,这是最常见的一种边界条件不正确引起的问题。
数组或者列表边界一般Review的点有以下几个:
1) 数组或列表的循环中,合法下标范围是0<=K
3、函数中途返回
函数中途返回指在运行过程中, 达到了某种条件, 使程序中途return的情况。如下面的代码所示,当info为空时直接返回了,乍一看似乎没有任何问题;但如果认真地思考后,会发现container对象还在等待一个回调,Review时需要去检查没有执行这个回调方法是否会存在问题。
因此针对类似的在中途返回的情况,Review时需要看看是否存在return导致某些逻辑不能正确执行到的情况。
4、内存泄漏
当程序偶尔出现莫名其妙的卡顿或异常,又或者Crash上报出现OOM异常时,那作为测试人员就该意识到程序有内存泄漏了。内存泄漏除了通过专门的测试方法来测试外,也可以通过代码Review来发现。
对QQ浏览器的内存泄漏测试发现的Bug原因分析,发现导致内存泄漏最频繁的原因不是图片资源或者IO流(Stream)未释放,而是注册了事件未取消注册引起的内存泄漏。
如下面的示例代码所示,FooActivity将自己注册到了FooDataManager,便于在数据发生变化时自己能收到通知。
如下面的代码所示,FooDataManager一般都会用一个列表来存储注册的监听者,如果FooDataManager需要运行很长时间甚至整个生命周期,或者listener本身是一个静态对象的话,那么listener会长期存在于内存中,这意味着listener中存放的对象也会被长期持有,最终导致内存泄漏。
前面示例中的FooActivity并未将自己反注册,listener一直持有该对象造成内存泄漏。
以上问题看起来似乎很简单,但是在浏览器项目中,即使高级的开发工程师也会犯类似的错误。当然内存泄漏的原因还有很多,这里就不全部列举了,大家可以网上搜索进行了解。
针对内存泄漏的情况,我一般会Review以下几种常见情况:
(1)对象如果注册了事件回调,是否在合理的地方进行了反注册;
(2)线程对象使用完毕是否正常的结束;
(3)各种数据库、网络连接和文件IO被打开后,是否正确关闭;
(4)图片资源正确释放;
(5)缓存对象要有一定的大小控制,且有明确的释放策略。
5、异常处理
关于异常处理的评审,笔者一般会关注当异常被捕获后,是否正确的处理,以及当有异常处理后,后续的流程是否正常执行。如下面的代码所示,当catch到异常时,此时looper是为空的,到后续的Handler初始化传入空的looper程序会出错。
效果
代码评审在QQ浏览器漫画模块最近了三个版本进行了实践,共发现Bug25个,如下面的截图所示。由于代码Reviwe在开发阶段就进行,Bug发现的时间提前了至少一周。总结
以上是我的一点经验总结,还需要持续积累。万事开头难,个人以为做代码Review在刚开始的时候会稍微难一些,但只要做到以下几点一定能做好代码Review。
第一,学会使用一些业界比较常用的代码扫描工具,可以快速入手;
第二,坚持学习提升自己的代码能力,并掌握快速阅读和理解代码的方法;
第三,加深对自己产品的业务和代码结构的理解,更容易发现深层问题。
最后,学会通过Bug根因分析,总结经验并应用于平时的工作中。
以上内容分享给大家,与大家共勉,希望我们一起进步!
关注微信公众号:腾讯移动品质中心TMQ,获取更多测试经验!
版权所属,禁止转载!
相关文章推荐
- 【腾讯TMQ】和开发一起写代码,让测试左移起来
- 【腾讯TMQ】JAVA代码覆盖率工具JaCoCo-原理篇
- 【腾讯TMQ】像google一样测试系列之五:流程与覆盖率篇
- 【腾讯TMQ】移动H5性能测试平台解决方案
- 【腾讯TMQ】MBT探索系列 – PRE/POST 模型在网络接口测试MBT的应用和探索
- 【腾讯TMQ】【Android场景化性能测试专栏】方向与框架篇
- 【腾讯TMQ】做测试计划需要考虑的方方面面
- 【腾讯TMQ】腾讯电量仪——智能硬件测试工具尝试之路
- 【腾讯TMQ】测试建模 从尔康的鼻孔说开来,重要的用例写三遍
- iOS 利用腾讯 Bugly 程序调试 测试代码bug 卡顿等情况
- 【腾讯TMQ】从插件重构看如何提升测试质量与效率
- 【腾讯TMQ】WIFI安全测试,其实不难
- 【腾讯TMQ】管中窥豹:结合NewApi实践来了解Lint代码扫描
- 【腾讯TMQ】【UTP自动化测试平台系列之终章】前端探索之路
- 【腾讯TMQ】在线沙龙|精准测试介绍
- 【腾讯TMQ】win32应用程序性能测试-内存篇
- 【腾讯TMQ】iOS静态代码扫描之工具调研
- 【腾讯TMQ】专治时间长 —5分钟测试Android覆盖安装
- 【腾讯TMQ】测试管理平台大比拼
- 【腾讯TMQ】接口测试用例设计