Android开发进阶——测试

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cwt8805/article/details/53128135

导言

每次使用Android Studio创建一个新的工程,都会看到类似如下的目录结构:
Android studio structure

我们编写的Java代码全部放在最上面的包中,下面两个使用红线圈中的包总是没有用过,仅仅知道他们是用于放置测试代码的。标注为androidTest的包放置UI相关的测试,标注为test的包放置普通的单元测试(使用jUnit4)。下面就来探索如何编写具体的测试代码。

测试金字塔

xx

如图,最基础的是Unit Test

Android里的测试类型

Unit Test

单元测试,用于测试小的功能点(如方法和类),不需要Android机器或者模拟器直接可以在开发机器上运行。可以使用的工具有jUnit和Robolectric。该类测试代码放到test中。

Instrumentation Test

UI测试,用于模拟用户与应用的交互,如点击按钮或者键入文字。可以使用的工具有Espresso、UIAutomator。该类测试代码放到androidTest中。

工程结构

为了方便测试,工程需要遵循一定的组织结构。这也是测试带来的一个间接好处,那就是代码必须要编写得低耦合。在这里我们选择MVP作为组织结构。
1. M代表Model,基本就是一些POJO
2. V代表View,一般使用Activity或者Fragment充当,View应该是纯被动的。
3. P代表Presenter,包含了所有View的展示逻辑和应用程序逻辑。从Repository中获取数据并在View中展示。尽量不要包含任何Android相关的代码。

单元测试的对象一般就是针对Presenter。

创建和运行单元测试代码

在要测试的目标类中使用快捷键,SHIFT+CTRL+T,然后选择创建新的测试。测试文件的命名一般就是在要测试的类后加上Test,如要测试LoginPresenter,那么测试相应的测试文件应该叫LoginPresenterTest。
编写测试用例,如下:

public class LoginPresenterTest {

    @Test
    public void checkLoginAttemptIsExceeded() {
        LoginPresenter loginPresenter = new LoginPresenter();
        Assert.assertEquals(1, loginPresenter.incrementLoginAttempt());
        Assert.assertTrue(loginPresenter.isLoginAttemptExceeded());
    }
}

测试类的测试用例方法需要使用@Test注解,方法名任意。
点击方法名左边出现的绿色三角形即可运行测试,或者右键测试类,然后选择运行该类中所有的测试方法。

使用Mockito

一般Presenter在创建的时候需要传递一个实现了某接口的View对象。那么就需要使用Mockito进行模拟一个实现了该接口的对象,首先在app module的build.gradle中添加依赖:

testCompile 'org.mockito:mockito-core:1.10.19'

然后如下使用:

public class LoginPresenterTest {

    @Test
    public void checkLoginAttemptIsExceeded() {
        LoginView loginView = mock(LoginView.class);
        LoginPresenter loginPresenter = new LoginPresenter(loginView);
        Assert.assertEquals(1, loginPresenter.incrementLoginAttempt());
        Assert.assertTrue(loginPresenter.isLoginAttemptExceeded());
    }
}

Integration Testing(Presenter和View是否衔接)

Presenter需要调用View的方法来进行展示,这个过程的测试就是Integration Test,参看前面的测试金字塔第二层。如下进行:

public class LoginPresenterTest {

    @Test
    public void checkUsernameAndPasswordIsCorrect() {
        LoginView loginView = mock(LoginView.class);
        LoginPresenter loginPresenter = new LoginPresenter(loginView);
        loginPresenter.doLogin("nilesh", "tdd");
        verify(loginView).showLoginSuccessMessage();
    }
}

使用Espresso进行UI测试

在app module的build.gradle中,添加依赖:

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

在同一个build.gradledefaultConfig节点中添加:

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

测试代码如下:

@RunWith(AndroidJUnit4.class)
public class LoginActivityTest {
    ActivityTestRule<LoginActivity> activityTestRule = 
        new ActivityTestRule<>(LoginActivity.class);

    @Test
    public void checkUserNameEditTextIsDisplayed() {
        activityTestRule.launchActivity(new Intent());
        onView(withId(R.id.edt_user_name)).check(matches(isDisplayed()));
    }

    @Test
    public void checkLoginSuccess() {
        activityTestRule.launchActivity(new Intent());
        onView(withId(R.id.edt_user_name)).perform(typeText("nj"), closeSoftKeyboard());
        onView(withId(R.id.edt_password)).perform(typeText("tdd"), closeSoftKeyboard());
        onView(withId(R.id.edt_user_name)).check(matches(isDisplayed())).perform(click());
        onView(withText("Login successful.")).check(matches(isDisplayed()));
    }
}

然后就可以连接Android手机或者虚拟机进行测试了。

猜你喜欢

转载自blog.csdn.net/cwt8805/article/details/53128135