如果你的单元测试没有依赖或者只有Android上的简单依赖,你应该在本地开发机器上运行测试。 这种测试方法是高效的,因为它可以帮助您避免每次运行测试时将目标应用程序和单元测试代码加载到物理设备或模拟器上的开销。 因此,运行单元测试的执行时间大大减少。 使用这种方法,通常使用模拟框架(如Mockito)来实现任何依赖关系。
配置测试环境
在您的Android Studio项目中,必须将用于本地单元测试的源文件存储在module-name / src / test / java /。 创建新项目时,此目录已存在。
您还需要为项目配置测试依赖关系,以使用JUnit 4框架提供的标准API。 如果您的测试需要与Android依赖关系交互,请包括Mockito库以简化本地单元测试。 要了解有关在本地单元测试中使用模拟对象的更多信息,请参阅下面的Mocking Android dependencies。
在应用程序的顶级build.gradle文件中,您需要将这些库指定为依赖关系:
dependencies {
// Required -- JUnit 4 framework
testCompile 'junit:junit:4.12'
// Optional -- Mockito framework
testCompile 'org.mockito:mockito-core:1.10.19'
}
创建一个本地单元测试类
你的本地单元测试类应该写成一个JUnit 4测试类。 JUnit是Java最受欢迎和广泛使用的单元测试框架。 这个框架的最新版本,JUnit 4,允许你以比它的前任版本更清洁和更灵活的方式编写测试。 与以前的基于JUnit 3的Android单元测试的方法不同,使用JUnit 4,您不需要扩展junit.framework.TestCase类。 您也不需要在测试方法名称前加上'test'关键字,或者使用junit.framework或junit.extensions包中的任何类。
要创建基本的JUnit 4测试类,请创建一个包含一个或多个测试方法的Java类。 测试方法以@Test注释开始,包含练习和验证要测试的组件中的单个功能的代码。
以下示例显示如何实现本地单元测试类。 测试方法emailValidator_CorrectEmailSimple_ReturnsTrue验证被测应用程序中的isValidEmail()方法是否返回正确的结果。
以下示例显示如何实现本地单元测试类。 测试方法emailValidator_CorrectEmailSimple_ReturnsTrue验证被测应用程序中的isValidEmail()方法是否返回正确的结果。
import org.junit.Test;
import java.util.regex.Pattern;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class EmailValidatorTest {
@Test
public void emailValidator_CorrectEmailSimple_ReturnsTrue() {
assertThat(EmailValidator.isValidEmail("name@email.com"), is(true));
}
...
}
要测试应用程序中的组件是否返回预期结果,请使用junit.Assert方法执行验证检查(或断言),以便将受测试组件的状态与某些预期值进行比较。 为了使测试更可读,可以使用Hamcrest matchers(例如is()和equalTo()方法)将返回的结果与预期结果进行匹配。
Mock Android dependencies
默认情况下,Gradle的Android插件针对android.jar库的修改版本执行本地单元测试,该版本不包含任何实际代码。 相反,从单元测试中调用Android类的方法会抛出异常。 这是为了确保你只测试你的代码,不依赖于Android平台的任何特定的行为(当没有明确模拟时)。
您可以使用模拟框架在代码中存根外部依赖关系,以便轻松测试您的组件是否按照预期的方式与依赖关系交互。 通过用模拟对象替换Android依赖项,您可以将单元测试与Android系统的其余部分隔离,同时验证这些依赖关系中的正确方法是否被调用。 Java的Mockito mocking框架(1.9.5及更高版本)提供了与Android单元测试的兼容性。 使用Mockito,您可以配置模拟对象以在调用时返回一些特定值。
要使用此框架将mock对象添加到本地单元测试,请遵循以下编程模型:
1> 在build.gradle文件中包含Mockito库依赖关系,如配置测试环境中所述。
2> 在单元测试类定义的开始,添加@RunWith(MockitoJUnitRunner.class)注释。 这个注释告诉Mockito测试运行器验证你的框架的使用是正确的,并简化了你的模拟对象的初始化。
3> 要为Android依赖项创建模拟对象,请在字段声明之前添加@Mock注释。
4> 要存根依赖关系的行为,可以使用when()和thenReturn()方法指定条件并返回值。
以下示例显示如何创建使用mock Context对象的单元测试。
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));
}
}
要了解有关使用Mockito框架的更多信息,请参阅Mockito API reference和示例代码中的SharedPreferencesHelperTest类。
如果Android.jar中的Android API抛出的异常对于测试有问题,您可以更改行为,以使方法通过在项目的顶级build.gradle文件中添加以下配置来返回null或零:
android {
...
testOptions {
unitTests.returnDefaultValues = true
}
}
警告:将returnDefaultValues属性设置为true应该小心。 null/零返回值可以在测试中引入回归,这难以调试,并且可能允许失败的测试通过。 只能使用它作为最后的手段。
运行本地单元测试
要运行本地单元测试,请按照下列步骤操作:
1> 通过单击工具栏中的Sync Project,确保您的项目与Gradle同步。
2> 使用以下方法之一运行测试:
a> 要运行单个测试,请打开“ Project”窗口,然后右键单击测试,然后单击Run。
b> 要测试类中的所有方法,请右键单击测试文件中的类或方法,然后单击Run。
c> 要在目录中运行所有测试,请右键单击目录并选择Run tests。
Gradle的Android插件编译位于默认目录(src / test / java /)中的本地单元测试代码,构建一个测试app,并使用默认的测试运行器类在本地执行它。 然后,Android Studio将在“ Run”窗口中显示结果。