【Android】测试

根据代码运行的位置可以将测试分为两类:本地单元测试和仪器测试。本地单元测试在计算机的本地JVM上运行,仪器测试在硬件设备或模拟器上运行。

本地单元测试

测试代码所在位置

module-name/src/test/java/

适用场景

当你的测试没有Android框架依赖项或者你可以模拟Android框架依赖项时使用本地单元测试。

优缺点

本地单元测试运行起来更加方便,执行时间更短。缺点是,当你的测试依赖很多Android框架时,需要使用Mockito之类的模拟库去模拟这些依赖于Android框架的类的行为。

JUnit + Mock是Android本地单元测试最常见的框架组合,JUnitMVP架构中测试Presenter层或者业务逻辑层

仪器测试

测试代码所在位置

module-name/src/androidTest/java/

适用场景

可以在编写集成或者UI测试时,或者在测试具有模拟对象无法满足的Android依赖项时使用仪器测试。

优缺点

仪器测试可以让你获取某些信息,比如测试的应用的Context,并且允许你通过测试代码来控制测试的应用。缺点是,仪器测试是内置于APK中的,当你修改了测试用例,就需要重新构建APK,然后push到设备中。

具体应用

分类 框架组合 具体应用 说明
本地单元测试 JUnit + Mock 测试MVP架构中的Presenter层或者业务逻辑层 Mock框架用于模拟Android框架依赖项
仪器测试 JUnit + AndroidJUnitRunner 测试DAO层 AndroidJUnitRunner使得JUnit测试能在Android设备上运行
仪器测试 JUnit + AndroidJUnitRunner + JUnit4 Rules + Esprosso 测试UI JUnit4 Rules用于测试Activity或者Service;Esprosso用于检测和控制UI

举例说明

例子来自谷歌官方提供的MVP架构示例代码

工程目录

【Android】测试_第1张图片
工程目录

test是本地单元测试代码所在的目录, androidTest是仪器测试代码所在的目录。 这里有一点需要注意,尽量让测试代码的包结构和main目录下的代码的包结构保持一致,这可以是测试代码的结构更加清晰。如下图所示, TaskPresenterTestTaskPresenter的测试,它们的包名保持一致。
【Android】测试_第2张图片
包结构保持一致

JUnit + Mock 测试Presenter层

工程配置

只需在模块的build.gradle中添加以下依赖:

dependencies {
    // Required -- JUnit 4 framework
    testImplementation 'junit:junit:4.12'
    // Optional -- Mockito framework
    testImplementation 'org.mockito:mockito-core:1.10.19'
}

举例说明

TasksPresenterTest为例(完整代码链接)。因为Presenter层是依赖于View层和Model层的,而View和Model层依赖Android框架,所以需要通过Mock框架模拟View层和Model层,具体的做法是给对应的类添加@Mock注解:

public class TasksPresenterTest {

    private static List TASKS;

    @Mock
    private TasksRepository mTasksRepository;

    @Mock
    private TasksContract.View mTasksView;

    ...

然后在执行测试用例之前初始化Mock:

   @Before
    public void setupTasksPresenter() {
        // Mockito has a very convenient way to inject mocks by using the @Mock annotation. To
        // inject the mocks in the test the initMocks method needs to be called.
        MockitoAnnotations.initMocks(this);

        ...

这个时候再去调用mTasksView或者mTasksRepository的方法,实际的代码并不会被执行,但是每个方法都会有默认的返回值,比如boolean会默认返回false。可以通过以下方法修改方法的返回值:

   @Before
    public void setupTasksPresenter() {
        ...

        // The presenter won't update the view unless it's active.
        when(mTasksView.isActive()).thenReturn(true);

        ...

这个时候再去调用mTasksView.isActive(),就会默认返回true。上面这个过程叫做stubbing,除了可以修改返回值,还可以让其在被调用的时候抛出异常或者执行实际的代码等。

完成Mock初始化和stubbing之后,就可以执行相应的代码,然后进行验证:

    @Test
    public void createPresenter_setsThePresenterToView() {
        // Get a reference to the class under test
        mTasksPresenter = new TasksPresenter(mTasksRepository, mTasksView);

        // Then the presenter is set to the view
        verify(mTasksView).setPresenter(mTasksPresenter);
    }

verify(mTasksView).setPresenter(mTasksPresenter)的意思是验证mTasksView.setPresenter(mTasksPresenter)是否被调用了,如果被调用了,则该测试用例通过测试,否则失败。

这里只介绍Mockito最常用也是最基本的功能,完整的详细的文档可以去Mockito的官网查看。

JUnit + AndroidJUnitRunner 测试DAO层

工程配置

举例说明

JUnit + AndroidJUnitRunner + JUnit4 Rules + Esprosso 测试UI

工程配置

举例说明

实战

切换照片变身模板
注意点:在fivesixapp这个module下编写测试代码;初始化

你可能感兴趣的:(【Android】测试)