android 测试开发概述

时间:2022-06-23 05:08:32

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)
@SmallTest
public 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测试库的用法,谢谢大家关注