通过Google官方Android App架构蓝图看测试

通过Google官方Android App架构蓝图看测试_第1张图片
Android测试.png

上周和大家分享了《Google官方Android App架构蓝图》,内容比较简单,没想到却收到了我在里面最多的喜欢,非常感谢大家。后来反思了一下,可能是因为借了Google大名,而内容虽然简单却很实用,很接地气,接下来我也尽量写一些接地气的文章,还望大家多多支持。其实上次写完了《Google官方Android App架构蓝图》,觉得有很重要的东西没有写到,憋屈了一周,这个东西就是里面的单元测试和UI测试。好的架构里面最重要的一点就是易于测试,接下来就让我们来八一八Google官方Android App架构蓝图Sample里面的单元测试。本文按照todo-mvp来写。

工程结构

通过Google官方Android App架构蓝图看测试_第2张图片
工程结构.png

我们可以看到这个Sample里面有3个测试目录:androidTest,androidTestMock和test。

androidTest

测试工具:espresso和hamcrest
目的:进行UI层测试,例如点击,跳转到某个页面
例子:

    @Test
    public void clickAddTaskButton_opensAddTaskUi() {
        // Click on the add task button
        onView(withId(R.id.fab_add_task)).perform(click());

        // Check if the add task screen is displayed
        onView(withId(R.id.add_task_title)).check(matches(isDisplayed()));
    }
androidTestMock

测试工具:espresso和hamcrest
目的:UI层测试mock数据支持
例子:

    @Test
    public void activeTaskDetails_DisplayedInUi() throws Exception {
        loadActiveTask();

        // Check that the task title and description are displayed
        onView(withId(R.id.task_detail_title)).check(matches(withText(TASK_TITLE)));
        onView(withId(R.id.task_detail_description)).check(matches(withText(TASK_DESCRIPTION)));
        onView(withId(R.id.task_detail_complete)).check(matches(not(isChecked())));
    }

    private void loadActiveTask() {
        startActivityWithWithStubbedTask(ACTIVE_TASK);
    }

    private void startActivityWithWithStubbedTask(Task task) {
        // Add a task stub to the fake service api layer.
        TasksRepository.destroyInstance();
        FakeTasksRemoteDataSource.getInstance().addTasks(task);

        // Lazily start the Activity from the ActivityTestRule this time to inject the start Intent
        Intent startIntent = new Intent();
        startIntent.putExtra(TaskDetailActivity.EXTRA_TASK_ID, task.getId());
        mTaskDetailActivityTestRule.launchActivity(startIntent);
    }
test

测试工具:mockito
目的:业务层单元测试,包括Data,Presenter等
例子:

    @Test
    public void saveNewTaskToRepository_showsSuccessMessageUi() {
        // Get a reference to the class under test
        mAddEditTaskPresenter = new AddEditTaskPresenter("1", mTasksRepository, mAddEditTaskView);

        // When the presenter is asked to save a task
        mAddEditTaskPresenter.createTask("New Task Title", "Some Task Description");

        // Then a task is saved in the repository and the view updated
        verify(mTasksRepository).saveTask(any(Task.class)); // saved to the model
        verify(mAddEditTaskView).showTasksList(); // shown in the UI
    }

测试工具

Espresso

Android自动化测试框架

Mockito

模拟测试框架,使我们可以在不涉及依赖关系的情况下测试代码

远程数据mock

客户端在开发过程中可能会遇到和服务端并行开发的情况,这时候就需要mock远程数据,但打包过程中就可能手动再把mock数据去除,非常麻烦,Sample里面就通过productFlavors来处理。

通过Google官方Android App架构蓝图看测试_第3张图片
远程数据Mock.png
productFlavors {
        mock {
            applicationIdSuffix = ".mock"
        }
        prod {}
    }

    // Remove mockRelease as it's not needed.
    android.variantFilter { variant ->
        if(variant.buildType.name.equals('release')
                && variant.getFlavors().get(0).name.equals('mock')) {
            variant.setIgnore(true);
        }
    }

我们可以看到,在开发过程中,使用mock过程下的FakeTasksRemoteDataSource,在release下会去除mock的包,只打出prod的包,这样就能避免mock的代码在release下被打入包内。

测试命令

test目录:用test命令
androidTest目录:用connectedAndroidTest命令

参考资料

todo-mvp
Mockito官网
Mockito介绍
Espresso官网

欢迎关注我的微博

你可能感兴趣的:(通过Google官方Android App架构蓝图看测试)