使用Instrumentation Test时,不能脱离手机验证代码的正确性,但是可以节省用户在手机上操作的时间,也就省去了在手机上反复重复操作的麻烦,也能直接输出测试结果,可以很明显的根据测试结果的颜色知道代码逻辑是否正常,而通常的自测还需要思考。这种方式的验证操作需要2min20s左右。
所以如果我们能使用JUnit的单元测试时,尽量使用这种单元测试,能极大地提升自测的效率,某些情况下不能使用JUnit的单元测试,这时候就适合使用 Instrumentation Test,比如,需要本地代码的测试,就需要使用Instrumentation Test。而如果只是依赖执行本地代码的类的话,可以用Robolectric + PowerMock +Mockito 进行模拟,模拟Native类的函数,使得调用Native类的函数返回预期的值即可实现模拟,进行正常的JUnit 单元测试。Robolectric将Android的Api在PC上做了重新实现,是一套非常强大的框架,支持Android的 SharedPreference,Environment, Context,甚至支持资源文件的使用(包括layout, drawable),这样我们的应用代码不用做任何改动,就可以使用Robolectric框架在PC上执行,因为Robolectric实现了 Android的api,并且能在PC上运行。正是因为它,才能使得我们能脱离手机进行测试,非常强大。
非主分支无法保证正常执行的问题
当我们测试某个功能函数时,可以为它的各个分支准备不同的测试函数,每个测试函数准备不同的测试参数,对这个功能函数进行测试,确保每个分支都能执行到。我们还可以用代码测试覆盖率工具来收集测试用例对各个分支的覆盖情况,比如jacoco工具,这样能确保各个分支都能被测试到。
需要持续回归测试的问题
我们可以通过和持续集成服务结合来解决这个问题。我们平常解决逻辑性Bug时,可以为这个Bug编写测试用例,每次在Gitlab或者 Github上如果在某个分支上更新了代码,则使得持续集成服务自动执行测试用例,这样下次修改Bug时,如果导致现有逻辑出现了问题,持续集成服务执行测试用例时,会发现错误,然后会发邮件通知提交代码的同事,说代码有问题,让其修改后提交。所有这些操作都是自动化的,可以节省大量人工测试时间,并且能提升测试效率。另外还可以将测试用例分成多组,比如SmallTest, LargeTest,MediumTest,在平常更新代码时只执行SmallTest分组的测试用例,合并代码时则执行LargeTest的测试用例,这样可以极大地节省持续回归测试的时间。
单元测试的局限性
从上面的论述看来,单元测试非常有用,但单元测试也有其局限性,整体的测试(集成测试)也是必不可少的。因为单元测试只能用于快速验证某个程序单元的实现是否有问题,而不能保证各个程序单元之间相互配合也没问题。
整体测试时也有自动化工具可以使用,比如Robotium, espresso,它们都是基于Android的Instrumentation Test实现的,也就是说如使用Robotium或者espresso编写好自动测试用例后,可以在手机上执行自动化测试操作。常规的上线前用例的测试可以使用这种自动化工具提升测试效率,不需要手动操作,如果逻辑有问题,自动化测试工具可以自动报告这种错误。
Espresso是Google写的,Google的工程师开始时也使用Robotium做自动化集成测试,在使用过程中发现存在不少问题,无法满足他们的需求,所以他们就重新实现了Espresso。Android Studio开发中的版本2.2_preview3能实现录制测试脚本,也就是说如果测试同学在手机上操作,AndroidStudio能将这些操作转换成基于espresso的java测试用例代码,然后下次测试时就可以直接执行这个测试用例了。所以如果想使用自动化的集成测试,还是建议使用 Espresso。
AndroidStudio2.2 preview 3中关于录制测试脚本的网址如下所示: http://tools.android.com/tech-docs/test-recorder
Espresso相比Robotium的优点:
同步。 默认情况下,instrumentation test的逻辑并没有在UI线程上执行,而是在单独的线程里执行。如果不对测试操作和UI更新进行同步,那这些测试容易出现偶然性问题,比如说,将会因为时间的因素而随机失败。大部分测试人员都会通过sleeps/retry等机制,甚至通过复杂的线程安全代码来进行测试。这几种做法都是不理想的。 Espresso可以做到在测试时无缝同步测试操作断言和应用的UI。Robotium通过sleeps/retry机制来处理这个问题,不仅不可靠,而且导致测试运行会更慢
API。 Espresso有更简洁的API, 并且能支持定制。你只需通过标准的Hamcrest matchers来定位UI元素,然后在这个元素上指定某个操作或者在这个元素上进行断言即可。而如果和Robotium的API相比,测试人员需要从 30多个click方法里进行选择。并且Robotium也暴露了一些危险的方法比如说getCurrentActivity以及getView,可以让你在非主线程上操作这些对象
原文转自: http://www.cloudchou.com/android/post-909.html