android测试的三大主体:
- 数据部分
各种repository,负责维护APP的数据源,包括本地缓存数据、服务器数据、共享数据、系统数据等。
- UI部分
各种控件的隐藏、显示、状态、内容、加载速度、交互事件等。
- 业务逻辑部分
各种Controller、Presenter、ViewModel,它作为数据和UI部分的粘合剂,负责处理用户交互以及加载、维护数据,使我们App具有各种完善的功能。
各部分的测试目的和要点
-
数据部分
数据部分对外是无依赖的,可以直接通过test或者androidTest方式来测试。数据部分的测试比较直接,并且重要性不言而喻。 -
业务逻辑部分
业务逻辑部分处于中间层,要测试它我们需要mock数据和UI对象,这需要良好的设计模式来支持,比如MVP、MVVM,而如果使用MVC模式,将业务逻辑写在Android组件里,是无法进行独立测试的,必须得结合UI测试才行。 -
UI测试
UI部分的测试,我们需要运行App才能进行测试,需要借助Espressor测试框架。和业务逻辑一样,如果我们要单独测试UI部分的功能,则要mock数据和业务逻辑对象。但是,一般来讲,我们使用的控件都是Android框架或者第三方开源的,是比较成熟的。因此我们针对UI部分的测试,更多地是通过UI模拟,来综合测试我们的UI交互和业务逻辑,而不是完全剥离开其他部分,只验证自己的控件,除非是想测试自己写的控件。
测试资源和依赖关系的处理
android 测试的方式有两种,一种是JUnit,直接编译源码运行在本机的jvm环境中,这种方式要求测试的目标类对android运行环境没有依赖。一种是AndroidJUnit,这种方式将代码部署到真实的android环境中运行,能够支持全方位的测试需求。android的开发环境为测试提供了单独的资源支持,每一个变体(BuildVirant)都会有对应的test和androidTest目录,用来存放res、manifest、代码。
通常而言,我们还要提供mock数据来进行测试,除了在测试代码中使用mock框架动态提供,我们还可以使用android框架的BuildVirant机制,分别为测试和生产环境提供一个变体,即mock和prod,让它们使用不同的数据来源,来提供静态的测试数据。这样的话,我们就有了额外的 2 * 2 + main 一共五个资源目录,可用于存放特定的资源了。那我们如何恰当地使用这些资源类型呢?
我们知道,测试的基本原理,就是控制变量法。即我们用已知的对象和逻辑,来验证我们要测试的对象和逻辑。那么在上面的三个主体中,要能够使用这种控制变量法,最基础的支持就是依赖关系的剥离。只有采用间接依赖,外部初始化其他主体成员的类,我们才能使用mock等技术对它进行独立的测试。
要剥离各主体部分的依赖关系,我们需要使用依赖注入的方式来完成,这样针对各主体部分的资源,我们可以将资源放在不同的目录下面,跟随变体(BuildVirant)进行动态替换。如果我们将资源直接放置到main目录下面,那么我们在生产和测试环境下,都将使用相同的资源。如果我们将它们分别放在mock和prod环境下(路径相同),那么它们就可以被区分开来。通常而言,我们只区分数据部分,因为测试和生产环境使用不同的业务逻辑和UI并不是我们想要的结果,虽然我们同样可以使用相同的方式来区分它们。
如果我们使用了依赖注入框架,比如dagger,它也同样遵循上述的变体规则,如果你想使用mock变体来提供静态测试数据,你可能需要将对应的dagger Module也分变体来实现。
网友评论