建议在阅读此篇文章之前,请先阅读《测试分类》,以便对Android 测试有个大致性的认识,现在,言归正传,回到如何构建
本地单元测试的问题上
如果你的单元测试没有依赖项或者仅仅有一些简单的Android依赖项,那么你应该在本地开发机上去运行你的测试。
这种测试的方式是非常高效的,因为它避免了去加载你的app和测试代码到真机或者模拟器上的开销。相应地,这种
单元测试所消耗的时间将会大大地减小。在这种方式下,你通常需要使用一个模拟的framework, 例如 Mockito,
去充当这种依赖关系。
搭建测试环境
在
Android Studio的工程下,你需要将本地单元的测试文件放在
module-name
/src/test/java/目录下,在你创建
一个新的工程的时候,这个目录就已经创建好了。
为了使你的工程能够使用 JUnit 4 framework提供的标准API,你需要配置一下这个测试的依赖项。如果你的测试需要与
Android 依赖项进行一个交互,需要包含
Mockito 库以便简化本地单元测试。如果想要了解更多关于在本地单元测试
在你app的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 4,你不用再去继承
junit.
framework.TestCase这个类,你也不用在你测试方法名前面添加一个“test”的前缀,也不用再去使用
junit.framework
or
junit.extensions
包下的类。
为了创建一个基本的JUnit 4测试类,你需要创建一个java类,然后让这个java类包含一个或多个测试方法。测试方法是以
@Test注解的方式开头,然后里边包含你想要执行的或者校验的功能。
下面这个示例展示了如何实现一个本地单元测试类。示例中的这个测试方法
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)); } ... }为了测试你app的组件是否返回期待的结果,你可以使用 junit.Assert 方法去比较组件的状态是否和某些期待的
结果一致。为了让这个测试更具有可读性,你可以使用
Hamcrest matchers (比如:is()和equalTo()方法)去比较
返回的结果和期待的结果。
模拟Android依赖项
这个
android.jar库实际上是不包含任何代码的。换言之,在本地单元测试中调用Android 类中的方法就会抛出异常。这
是为了确保在你的测试代码中没有去使用Android平台相关的东西。
为了能方便地地测试那些与依赖项相关联的组件,在代码中,你可以使用一个模拟的框架去解决这个外部依赖项的问题。
通过使用一个模拟对象去替代Android 依赖项,这样你就可以把你的单元测试与Android 系统的其他部分予以分开。针对
java平台而开发
Mockito 这个模拟框架兼容Android单元测试。有了它,当被调用之时,你就可以让这个模拟对象返回
某些特定的值。
在使用这个框架的时候,为了能够添加一个模拟对象到你的本地单元测试中,需要遵循以下步骤:
2>在单元测试类定义的开头部分,添加
@RunWith(MockitoJUnitRunner.class)注释。这个注释是为了判断Mockito
这个框架是否被正确地使用以及简化了模拟对象初始化的工作。
3>因Android 依赖项去创建一个模拟对象,需要在这个属性声明之前添加一个 @Mock 的注释。
4>为了判断依赖项的状态,你可以通过通过使用when()然后thenReturn()的方法去指定一个条件,在某个条件满足之时,就让其返回某个值。
下面这个例子展示了如何使用一个模拟的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 和 sample code 中的SharedPreferencesHelperTest类。
运行本地单元测试
运行本地单元测试,请遵循以下步骤:
1>
确保你的工程文件已通过 按钮 Sycn Project 进行了更新操作
2>
用其中一种方式去运行你的测试文件:
I>
运行单个测试,可以打开Project窗体,然后右键单击这个测试文件,然后点击 Run
II>
运行一个类中的所有方法,可以在测试文件中右键单击类或者方法,然后点击Run
III>
运行目录下所有的测试文件,右键单击这个目录,然后选择 Run tests