android 测试开发概述

来源:互联网 发布:centos无线网卡配置 编辑:程序博客网 时间:2024/05/29 18:35

android测试主要有两种

1.本地测试(local test)

只在计算机中运行,这些测试运行在本地JVM中以减少执行时间。这种测试适合不需要android framework或者可以用模拟出的依赖来代替的测试。


2.设备测试(instrumentation test)

运行在android设备或者模拟器上的测试。这些测试需要使用到设备信息,如app的context。这种测试适合难以用mock代替的对象以及UI测试。


在最新的android studio(版本2.0)中,project已经分好了androidTest和test两个部分,前者用于设备测试,后者用于本地测试,从example中可见出区别。


以下详细讲两种测试的步骤:


本地测试

首先要配置好gradle的依赖信息

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


我们应该使用JUnit4来进行我们的测试开发。使用JUnit4,我们不再需要继承junit.framework.TestCase,我们也不再需要在方法名前以test作为前缀。

我们需要的是在测试方法前加上@Test的注释


我们可以用junit.Assert方法检车我们的返回值和期望值是否相同。

如果想让测试更加可读,我们可以使用Hamcrest matchers来进行匹配。


例如现在我们有一个User类

public class User{    private String name;    private int age;    public User(String name, int age) {        this.name = name;        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}
现在我们在测试中模拟一个用户,然后创建一个用户

将两个getAge方法进行对比

public class ExampleUnitTest {    @Mock    User mockUser;    User user;    @Before    public void setup(){        MockitoAnnotations.initMocks(this);        when(mockUser.getAge()).thenReturn(20);        user = new User("haha",20);    }    @Test    public void checkAge(){        assertEquals(mockUser.getAge(),user.getAge());    }}

以下是android官方文档的sample:android文档传送门

import static org.hamcrest.MatcherAssert.assertThat;import static org.hamcrest.CoreMatchers.*;import static org.mockito.Mockito.*;import org.junit.Test;import org.junit.runner.RunWith;import org.mockito.Mock;import org.mockito.runners.MockitoJUnitRunner;import android.content.SharedPreferences;@RunWith(MockitoJUnitRunner.class)public class UnitTestSample {    private static final String FAKE_STRING = "HELLO WORLD";    @Mock    Context mMockContext;    @Test    public void readStringFromContext_LocalizedString() {        // Given a mocked Context injected into the object under test...        when(mMockContext.getString(R.string.hello_word))                .thenReturn(FAKE_STRING);        ClassUnderTest myObjectUnderTest = new ClassUnderTest(mMockContext);        // ...when the string is returned from the object under test...        String result = myObjectUnderTest.getHelloWorldString();        // ...then the result should be the expected one.        assertThat(result, is(FAKE_STRING));    }}
在官方例子中,就用了mock处理Context的问题


在左侧项目列表中右击类名,然后点击Run就可以运行该类,运行结束后就可以看到XX test passed,xx test failed的结果

mock的用法有很多,详细大家可以看《android开发进阶——从小工到专家》里面的介绍

给大家一个mockito官方文档的传送门:mock传送门


设备测试

设备测试运行在模拟器或者真机上,适合需要设备信息(如context)后者需要android framework组件(如Parcelable 或者 SharedPreference),可以减少mock的对象。
使设备测试还可以充分利用好android framework API,例如android testing support library。


和本地测试一样,我们要配置好测试库的依赖
dependencies {    androidTestCompile 'com.android.support:support-annotations:23.0.1'    androidTestCompile 'com.android.support.test:runner:0.4.1'    androidTestCompile 'com.android.support.test:rules:0.4.1'    // Optional -- Hamcrest library    androidTestCompile 'org.hamcrest:hamcrest-library:1.3'    // Optional -- UI testing with Espresso    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'    // Optional -- UI testing with UI Automator    androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1'}

这里的测试库包括了JUnit4和用于UI测试的Espresso和UI Automator(两者分别用于白盒测试和黑盒测试,选择自己需要的来用就好了)
Hamcrest是用于让断言(assert)函数更容易使用


为了让JUnit成为我们默认的测试运行器,我们需要在app 模块gradle文件中添加
android {    defaultConfig {        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    }}
例如这样:
<span style="font-family: Arial, Helvetica, sans-serif;">apply plugin: 'com.android.application'</span>
android {    compileSdkVersion 22    buildToolsVersion "22"    defaultConfig {        applicationId "com.my.awesome.app"        minSdkVersion 10        targetSdkVersion 22.0.1        versionCode 1        versionName "1.0"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    }}dependencies {    // App's dependencies, including test    compile 'com.android.support:support-annotations:22.2.0'    // Testing-only dependencies    androidTestCompile 'com.android.support.test:runner:0.5'    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'}

创建测试类时要在前面加上@RunWith(AndroidJUnit4.class)
下面是范例

import android.os.Parcel;import android.support.test.runner.AndroidJUnit4;import android.util.Pair;import org.junit.Test;import org.junit.runner.RunWith;import java.util.List;import static org.hamcrest.Matchers.is;import static org.junit.Assert.assertThat;@RunWith(AndroidJUnit4.class)@SmallTestpublic class LogHistoryAndroidUnitTest {    public static final String TEST_STRING = "This is a string";    public static final long TEST_LONG = 12345678L;    private LogHistory mLogHistory;    @Before    public void createLogHistory() {        mLogHistory = new LogHistory();    }    @Test    public void logHistory_ParcelableWriteRead() {        // Set up the Parcelable object to send and receive.        mLogHistory.addEntry(TEST_STRING, TEST_LONG);        // Write the data.        Parcel parcel = Parcel.obtain();        mLogHistory.writeToParcel(parcel, mLogHistory.describeContents());        // After you're done with writing, you need to reset the parcel for reading.        parcel.setDataPosition(0);        // Read the data.        LogHistory createdFromParcel = LogHistory.CREATOR.createFromParcel(parcel);        List<Pair<String, Long>> createdFromParcelData = createdFromParcel.getData();        // Verify that the received data is correct.        assertThat(createdFromParcelData.size(), is(1));        assertThat(createdFromParcelData.get(0).first, is(TEST_STRING));        assertThat(createdFromParcelData.get(0).second, is(TEST_LONG));    }}
我们还可以 创建一个以.suite结尾的包,在里面创建一个UnitTestSuite类,在类前加上@RunWith(Suite.class)@Suite.SuitClasses() 

在SuiteClasses中列出测试用例

例子:
import com.example.android.testing.mysample.CalculatorAddParameterizedTest;import com.example.android.testing.mysample.CalculatorInstrumentationTest;import org.junit.runner.RunWith;import org.junit.runners.Suite;// Runs all unit tests.@RunWith(Suite.class)@Suite.SuiteClasses({CalculatorInstrumentationTest.class,        CalculatorAddParameterizedTest.class})public class UnitTestSuite {}


在后面我还会讲述UI测试库的用法,谢谢大家关注

0 0