浅谈测试

126 阅读6分钟

什么是测试

Android官方测试教程

测试是开发过程中,很重要的一部分。

Android官方资料里,将测试划分成三大部分:

单元测试(Unit Tests):是针对最小代码单元的测试。面向对象编程,最小的代码单元就是方法。单元测试,也就是校验一个类的某个方法,比如在MVP里,校验某个Model的某个方法。

集成测试(Integration Tests):相对于单元测试,测试的范围进行了扩大。验证模块内堆栈级别之间的交互,或相关模块之间的交互。可以简单地理解为,集成测试,是跨多个代码单元,跨多个模块。比如在MVP里,校验Presenter层与Model层的交互。

端对端测试(End-to-end Test):官方又视其为UI测试(UI Tests)。相对于集成测试,测试的范围进一步扩大。主要验证与用户的交互。比如用户在登录界面,输入账户密码,点击跳转按钮后,是否正确跳转到用户主页。如果是在MVP里,这个操作,就同时涉及到了View、Presenter、Model三层。

测试目录

Android Studio中的项目通常包含两个放置测试的目录:androidTesttest

androidTest:放含有android相关类,需要使用到虚拟机或真机帮助运行的测试代码。此类测试包括集成测试,端到端测试以及仅JVM无法验证应用程序功能的其他测试。

test:放纯java,能在jvm上直接运行的测试代码,例如单元测试。

各类测试的比重

官方建议上述三类测试在项目中的比重:70%单元测试,20%集成测试,10%UI测试。

为什么需要测试

1)更快的故障反馈

就拿单元测试来说:

假设你需要从水电厂拼接一批水管到住处时,但这批“菜鸡出品,常有次品”的水管,有待检测。最憨的方法是一根根拼接好,然后从水电厂注水,查看整体情况,揪出有问题的水管,修复,最后再注水看看效果,周而复始。但这样,每注一次水,要耗费的时间太长了。

但如果你有多辆可以移动的小型水车,它们有注水的能力。你可以用它们同时给多根水管,分别注水,然后就能快速得到每根水管的质量状况。一有问题,马上修复,然后再给有问题的水管单独注水,看看其修复没有。这样一来,效率可以说是大大提高。

真机,就像水电厂。单元测试,就像数量庞大的水车。而待测试的方法则是我们的水管。如果没有对应的单元测试,你可能噼里啪啦,敲完了一通代码,然后跑一遍真机,再然后,一个个界面跳转,跳到你新写的代码那里。哎哟,空指针?小意思,立马改完。再跑跑看,再一页页跳转。堆栈溢出...

更可怕的是,我们通常一次只能定位到一个错误。然后一遍又一遍尝试跑真机查看修复效果,效率低得令人发指。

单元测试,最大的特点,就是快,跑一遍测试,快则不到1秒,慢通常也不到10秒。跑几十次单元测试,可能你的app还没刷到真机上一次。用它来检测你写得没那么自信的方法,你就可以很直观、迅速地观察到方法是否按你预想的执行。

2)更全面的检验

测试,还可以模拟各种情况,就相当于能提供不同的“水车”,给你的方法注入不同的“水”(方法参数),来检测你的待测方法是否经得住各种情况的考验。

3)更安全的重构

测试,也能让代码设计更合理,提高代码的可维护性。也方便你将来重构代码。使用单元测试调试修改方法的过程,也算是一次“小重构”。

当你意识到,你要为一个方法写单元测试的时候,你会下意识地考虑,怎么写才能让它更易于测试。而易于测试的代码,通常更加合理,设计更好。因为你是站在维护者的角度,去设计你的代码的。

4)更好的代码“注释”

测试代码也是非常好的代码注释。后来者,也可以根据以前留下来的测试代码,更好地理解并调试修改你的代码,并且通过运行以前留下来的测试,能够更好地避免新增的业务逻辑影响到旧代码。我想在座各位,应该都尝试过修改公司的祖传代码。没有详细代码注释,没有业务流程说明,几年的代码迭代下来,各种看不懂的迷之字段和逻辑。问产品,产品可能也一问三不知,因为他可能也是刚来的。然后,你增加了新的业务逻辑,殊不知补了西墙,却拆了东墙。然后代码到了测试手上,转手就给你提了一堆Bug。

综上,搬运一下官方的说法,测试的好处如下:

1)故障快速反馈

2)开发周期中的早期故障检查

3)更安全的代码重构,让你优化代码而不用担心回归测试

4)稳定的开发速度,帮助你最小化技术债务

所以,学学测试吧。就当可怜你那日益稀疏的头发~

一定需要测试吗

好了。前面吹完,现在来打脸了。

其实很多时候都用不上。特别是中小公司这种,代码质量又差,如果中途引入测试,特别是单元测试,过程是很痛苦的。而测试这种东西,是随着版本迭代,才越来越有用。短时间内其实是很难看到收益的。这时候,要是耽误了发版,谁背锅?

领导吗?不阔能。

产品吗?他负责写代码吗?对不起,他负责找茬。上个版本的需求,下个版本又干掉的人,你忘记是谁了吗?

所以,这种情况,可以酌情写部分测试,测试自己新增的代码即可。

测试小知识

1.测试的代码,在打包时,不会被编译进apk里。所以不需要担心会增大apk体积。

2.国外非常流行测试。如果你从github里下拉RxJava、Retrofit、OkHttp这些著名开源框架的源码,你会发现它们里面都有大量的单元测试。而这些单元测试,能帮助你很好地理解作者的意图,更好地阅读、学习这些源码。

所以,学习这些框架,特别是RxJava。正确的姿势,不是过多地翻阅各种参差不齐的博客,而是看源码,看里面的测试,甚至自己尝试写测试,了解RxJava的各种操作符的特性。

测试利器

JUnit、Mockito、PowerMock、Robolectric、Espresso等是现在比较流行的测试框架,为android测试提供了便利。

其中,JUnit是Java测试里最基本的框架。Mockito、PowerMock、Robolectric主要用于写单元测试。Espresso主要用于写集成测试、端对端测试。

它们的集成、使用以及配合使用,将会在下面的文章进行介绍:

浅谈测试之JUnit

浅谈测试之Mockito

浅谈测试之PowerMock

浅谈测试之Robolectric

浅谈测试之Espresso